/* QWE -- Quick Waveform Editor for Mirage psl 8/87 */ #include #include #include #include #include #include #include #include #define DATAWIDTH 1024 #define DATAHEIGHT 256 #define MARGIN 1 #define VIEWWIDTH (DATAWIDTH+2*MARGIN) #define VIEWHEIGHT (DATAHEIGHT+2*MARGIN) #define SCROLLHEIGHT 20 #define PANELHEIGHT 64 #define BORDER 16 #define MISC 16 #define BPP 256 #define DSCMAGIC 05504 #define OUTFILE "qwe.data" #define TMPFILE "/tmp/qwe.tmp" #define WDRFILE "/tmp/qwe.wdr" #define SEQFILE "/tmp/qwe.seq" #define PIX_INV PIX_NOT(PIX_DST) #define PIX_XOR (PIX_DST^PIX_SRC) #define ROP(OX,OY,CX,CY,OP) pw_rop(Dpw,OX,OY,CX-(OX),CY-(OY),OP,0,0,0); #define RECTOP(R,OP) ROP((R).o.x,(R).o.y,(R).c.x,(R).c.y,OP) #define RINV(OX,OY,CX,CY) pw_rop(Dpw,OX,OY,CX-(OX),CY-(OY),PIX_INV,0,0,0); #define RECTINV(R) RINV((R).o.x,(R).o.y,(R).c.x,(R).c.y) #define B_TO_PIX(B) (MARGIN+((B)*Ppp)/BPP) #define D_TO_PIX(D) (BORDER+MARGIN+0xFF-(D)) #define S_TO_PIX(S) (BORDER+MARGIN+0x7F-(((S)+2)>>2)) #define PIX_TO_B(P) ((((P)-MARGIN)*BPP)/Ppp) #define PIX_TO_D(P) (BORDER+MARGIN+0xFF-(P)) #define PIX_TO_S(P) ((BORDER+MARGIN+0x7F-(P))<<2) #define D_TO_NUM(D) ((D)-0x80) #define NUM_TO_D(N) ((N)+0x80) typedef unsigned char uchar; #define NUMSCALE 256 struct scstr { int bpos; /* byte position */ short scale; /* scale * 256 */ } Scale[NUMSCALE] = { { 0, 256, }, { 65536, 256, }, }; int Nscale = 2; /* number of points in the scaling fcn */ char Oldfile[128]; /* where the data comes from for "read" */ char Flbuf[128]; /* frame label buffer */ uchar *Data; /* pointer to wavesample (sbrk) */ int Chan = 2; /* Where the Mirage listens */ int Pcnt = 0; /* data page count */ int Ppp = 16; /* pixels/page (magnification) */ int Tticks = BPP; /* bytes per tickmark (time ticks) */ int Aticks = 128; /* values per tickmark (amplitude ticks) */ int Ramt = 1; /* rotation amount */ int Cbusy = 0; /* semaphore, to hide cursor while busy */ Pixrect *Grey; /* grey texture */ Frame Dframe; /* whole display's frame */ Canvas Dlborder; /* left border */ Canvas Dcanvas; /* waveform area */ Scrollbar Dcsb; /* waveform area's scrollbar */ int Dcwidth, Dcheight; /* width & height of Dcanvas */ Pixwin *Bpw = 0; /* display pixwin for border area (Dborder) */ Pixwin *Dpw = 0; /* display pixwin for waveform area (Dcanvas) */ Panel Controls; /* control panel */ Panel_item Mslide; /* id for magnification slider */ Panel_item Tslide; /* id for time ticks slider */ Panel_item Aslide; /* id for amplitude ticks slider */ Panel_item Rslide; /* id for rotation amount slider */ /* Button 3 menu */ Menu b3mp; #define PLAY 1 #define DUMP 2 #define LOAD 3 #define ROTL 4 #define ROTR 5 #define TRIM 6 #define SCALE 7 #define NORMALIZE 8 #define READ 9 #define WRITE 10 #define READDSC 11 #define WRITEDSC 12 #define QUIT 13 #define B3MINIT() b3mp = menu_create( \ MENU_INITIAL_SELECTION, MENU_SELECTED, \ MENU_INITIAL_SELECTION_SELECTED, FALSE, \ MENU_STRINGS, \ "PLAY SEQ", \ "MIRAGE->QWE", \ "QWE->MIRAGE", \ "ROT LEFT", \ "ROT RIGHT", \ "TRIM", \ "SCALE", \ "NORMALIZE", \ "READ", \ "WRITE", \ "READ DSC", \ "WRITE DSC", \ "QUIT", \ 0, 0) short Grey_bits[] = { 0xAAAA, 0x5555, 0xAAAA, 0x5555, 0xAAAA, 0x5555, 0xAAAA, 0x5555, 0xAAAA, 0x5555, 0xAAAA, 0x5555, 0xAAAA, 0x5555, 0xAAAA, 0x5555, }; main(argc, argv) char *argv[]; { extern FILE *sopen(); /****/setbuf(stderr, 0); /* THOSE ASSHOLES AT SUN! */ while (--argc > 0) { if (argv[argc][0] == '-') { switch (argv[argc][1]) { case 'm': /* magnify */ Ppp = atoi(&argv[argc][2]); if (Ppp < 1 || Ppp > BPP) goto syntax; break; default: goto syntax; } } else if (*Oldfile == 0) sprintf(Oldfile, "%s", argv[argc]); else { syntax: fprintf(stderr, "Usage: %s [-m#] [file]\n", argv[0]); exit(2); } } if (readdata(Oldfile) == 0) /* no file read */ exit(1); miscinits(); redraw(); window_main_loop(Dframe); exit(0); } redraw() { busy_cursor(); drawdata(); drawticks(); flipscale(); ready_cursor(); } drawdata() { register int i, x, y, ox, oy, nbytes; pw_writebackground(Dpw, 0, BORDER, Dcwidth, VIEWHEIGHT, PIX_CLR); if (Dpw) pw_batch_on(Dpw); nbytes = BPP * Pcnt; ox = oy = -1; for (i = 0; i < nbytes; i++) { x = B_TO_PIX(i); y = D_TO_PIX(Data[i] & 0xFF); if (ox >= 0) pw_vector(Dpw, ox, oy, x, y, PIX_SET, 1); ox = x; oy = y; } if (Dpw) pw_batch_off(Dpw); } drawticks() { register int i, x, nbytes, h2; if (Dpw) pw_batch_on(Dpw); nbytes = BPP * Pcnt; pw_writebackground(Dpw, 0, 0, Dcwidth, BORDER, PIX_CLR); if (Tticks) { for (i = 0; i < nbytes; i += Tticks) { x = (i * Ppp) / BPP; pw_vector(Dpw, x, 0, x, BORDER, PIX_SRC, 1); } } pw_writebackground(Bpw, 0, 0, BORDER, DATAHEIGHT, PIX_CLR); h2 = 0x80; pw_vector(Bpw, 0, h2, BORDER, h2, PIX_INV, 1); if (Aticks) { for (i = Aticks; i < h2; i += Aticks) { pw_vector(Bpw, 0, h2 + i, BORDER, h2 + i, PIX_INV, 1); pw_vector(Bpw, 0, h2 - i, BORDER, h2 - i, PIX_INV, 1); } } if (Dpw) pw_batch_off(Dpw); return(1); } flipscale() /* XOR the scale line in */ { register int i, x, y, ox, oy; if (Nscale < 1) return; x = B_TO_PIX(Scale[0].bpos); y = S_TO_PIX(Scale[0].scale); if (Nscale == 1) pw_vector(Dpw, B_TO_PIX(0), y, B_TO_PIX(Pcnt*BPP), y, PIX_INV, 1); else { for (i = 1; i < Nscale; i++) { ox = x; oy = y; x = B_TO_PIX(Scale[i].bpos); y = S_TO_PIX(Scale[i].scale); pw_vector(Dpw, ox, oy, x, y, PIX_INV, 1); } } } upmisc() /* update misc - canvas size, frame label, etc. */ { sprintf(Flbuf, "-=[ QWE ]=- %s, %d page%s", Oldfile, Pcnt, Pcnt==1? "" : "s"); window_set(Dframe, FRAME_LABEL, Flbuf, 0); Dcwidth = Ppp * Pcnt; window_set(Dcanvas, CANVAS_WIDTH, Dcwidth, 0); scrollbar_scroll_to(Dcsb, 0); panel_set(Mslide, PANEL_VALUE, Ppp, 0); } miscinits() /* do one-time inits */ { Rect tmp; Cursor cursor; void input(); tmp.r_left = 8; tmp.r_top = 8; /**** tmp.r_width = BORDER + MARGIN + VIEWWIDTH + MISC; /****/ tmp.r_width = BORDER + MARGIN + VIEWWIDTH; tmp.r_height = BORDER + MARGIN + VIEWHEIGHT /**** + SCROLLHEIGHT + MARGIN + PANELHEIGHT + MISC; /****/ + MARGIN + PANELHEIGHT + MISC; Dframe = window_create(NULL, FRAME, FRAME_OPEN_RECT, &tmp, 0); Dlborder = window_create(Dframe, CANVAS, CANVAS_FIXED_IMAGE, TRUE, WIN_X, 0, WIN_Y, BORDER, WIN_WIDTH, BORDER, WIN_HEIGHT, VIEWHEIGHT, 0); Dcsb = scrollbar_create( SCROLL_DIRECTION, SCROLL_HORIZONTAL, SCROLL_PLACEMENT, SCROLL_SOUTH, SCROLL_THICKNESS, SCROLLHEIGHT, 0); Dcwidth = Ppp * Pcnt; Dcanvas = window_create(Dframe, CANVAS, CANVAS_FIXED_IMAGE, TRUE, CANVAS_AUTO_SHRINK, FALSE, WIN_X, BORDER + MARGIN, WIN_Y, 0, WIN_WIDTH, VIEWWIDTH, CANVAS_WIDTH, Dcwidth, WIN_HEIGHT, BORDER + VIEWHEIGHT + SCROLLHEIGHT, CANVAS_HEIGHT, BORDER + VIEWHEIGHT, WIN_HORIZONTAL_SCROLLBAR, Dcsb, WIN_CURSOR, cursor_create( CURSOR_SHOW_CROSSHAIRS, TRUE, 0), WIN_CONSUME_PICK_EVENTS, WIN_NO_EVENTS, LOC_WINENTER, LOC_WINEXIT, LOC_MOVE, WIN_MOUSE_BUTTONS, 0, WIN_EVENT_PROC, input, 0); Bpw = canvas_pixwin(Dlborder); Dpw = canvas_pixwin(Dcanvas); Grey = mem_point(16, 16, 1, Grey_bits); B3MINIT(); gencntl(); upmisc(); } gencntl() { int swidth; void cntlchng(); swidth = 258; Controls = window_create(Dframe, PANEL, WIN_X, 0, WIN_Y, BORDER + VIEWHEIGHT + SCROLLHEIGHT, WIN_WIDTH, WIN_EXTEND_TO_EDGE, WIN_HEIGHT, PANELHEIGHT, PANEL_SHOW_MENU, FALSE, PANEL_LABEL_BOLD, TRUE, PANEL_ITEM_X_GAP, 25, 0); Mslide = panel_create_item(Controls, PANEL_SLIDER, PANEL_LABEL_STRING, "PIXELS/PAGE", PANEL_SLIDER_WIDTH, swidth, PANEL_VALUE, Ppp, PANEL_MIN_VALUE, 4, PANEL_MAX_VALUE, BPP, PANEL_NOTIFY_PROC, cntlchng, 0); Tslide = panel_create_item(Controls, PANEL_SLIDER, PANEL_LABEL_STRING, " BYTES/TICK", PANEL_SLIDER_WIDTH, swidth, PANEL_VALUE, Tticks, PANEL_MIN_VALUE, 2, PANEL_MAX_VALUE, BPP, PANEL_NOTIFY_PROC, cntlchng, 0); Aslide = panel_create_item(Controls, PANEL_SLIDER, PANEL_LABEL_STRING, "VALUES/TICK", PANEL_SLIDER_WIDTH, swidth, PANEL_VALUE, Aticks, PANEL_MIN_VALUE, 2, PANEL_MAX_VALUE, 128, PANEL_NOTIFY_PROC, cntlchng, 0); Rslide = panel_create_item(Controls, PANEL_SLIDER, PANEL_LABEL_STRING, " ROTATE AMT", PANEL_SLIDER_WIDTH, swidth, PANEL_VALUE, Ramt, PANEL_MIN_VALUE, 1, PANEL_MAX_VALUE, BPP, PANEL_NOTIFY_PROC, cntlchng, 0); window_fit_height(Controls); } void cntlchng(item, value, event) Panel_item item; Event *event; { if (item == Mslide) { if (Ppp != value) { pw_writebackground(Dpw, 0,BORDER, Dcwidth,VIEWHEIGHT, PIX_CLR); Ppp = value; upmisc(); redraw(); } } else if (item == Tslide) { if (Tticks != value) { Tticks = value; drawticks(); } } else if (item == Aslide) { if (Aticks != value) { Aticks = value; drawticks(); } } else if (item == Rslide) Ramt = value; } busy_cursor() { Cursor cursor; if (Cbusy++ == 0) { /****/fprintf(stderr, "busy... "); #ifdef NOTHING_WORKS cursor = window_get(Dframe, WIN_CURSOR); cursor_set(cursor, CURSOR_SHOW_CROSSHAIRS, FALSE, 0); window_set(Dframe, WIN_CURSOR, cursor, 0); /****/window_release_event_lock(Dframe); #endif } return(Cbusy); } ready_cursor() { Cursor cursor; if (--Cbusy <= 0) { /****/fprintf(stderr, "\n"); #ifdef NOTHING_WORKS cursor = window_get(Dframe, WIN_CURSOR); cursor_set(cursor, CURSOR_SHOW_CROSSHAIRS, TRUE, 0); window_set(Dframe, WIN_CURSOR, cursor, 0); #endif Cbusy = 0; } return(Cbusy); } void input(window, event, arg) Window window; Event *event; { register int i, change; i = event_id(event); if (i != MS_LEFT && i != MS_MIDDLE && i != MS_RIGHT) return; busy_cursor(); change = 0; if (i == MS_LEFT) change = mouseleft(window, event); else if (i == MS_MIDDLE) change = mousemiddle(window, event); else if (i == MS_RIGHT) change = mouseright(window, event); if (change) redraw(); ready_cursor(); } mouseleft(window, event) Window window; Event *event; { char tbuf[64], vbuf[64], abuf[64]; int x, y, byte, val, p, b; Menu m; if (!event_is_down(event)) return(0); x = event_x(event); y = event_y(event); byte = PIX_TO_B(x); val = PIX_TO_D(y); p = byte / BPP; b = byte % BPP; sprintf(tbuf, "%d page%s, %d byte%s", p, p==1? "" : "s", b, b==1? "" : "s"); sprintf(vbuf, "Crosshair: %d", val); sprintf(abuf, "Amplitude: %d", Data[byte]); m = menu_create(MENU_STRINGS, tbuf, vbuf, abuf, 0, 0); menu_show(m, window, event, 0); menu_destroy(m); return(0); } mousemiddle(window, event) Window window; Event *event; { char tbuf[64], vbuf[64], abuf[64], dbuf[64]; int i, byte, p, b, val, j, di; Menu m; if (!event_is_down(event)) return(0); byte = PIX_TO_B(event_x(event)); val = PIX_TO_S(event_y(event)); p = byte / BPP; b = byte % BPP; sprintf(tbuf, "%d page%s, %d byte%s", p, p==1? "" : "s", b, b==1? "" : "s"); sprintf(vbuf, "Data:%d, Scale:%g", Data[byte], val / 256.); sprintf(abuf, "ADD %g @ %d?", val / 256., byte); if (Nscale > 0) { for (di = 0; di < Nscale-1 && byte > Scale[di].bpos; di++); if (di > 0 && Scale[di].bpos - byte > byte - Scale[di-1].bpos) --di; sprintf(dbuf, "DEL %g @ %d?", Scale[di].scale / 256., Scale[di].bpos); m = menu_create(MENU_STRINGS, "SCALING", tbuf, vbuf, abuf, dbuf, 0, 0); } else m = menu_create(MENU_STRINGS, "SCALING", tbuf, vbuf, abuf, 0, 0); i = (int) menu_show(m, window, event, 0); menu_destroy(m); flipscale(); if (i == 4) { /* add a new point */ for (i = 0; i < Nscale && byte > Scale[i].bpos; i++); if (i < Nscale && byte == Scale[i].bpos) { if (val != Scale[i].scale) Scale[i].scale = val; } else if (Nscale >= NUMSCALE) { printf("Too many scale points.\n"); } else { if (i < Nscale) for (j = Nscale; --j >= i; Scale[j+1] = Scale[j]); Nscale++; Scale[i].bpos = byte; Scale[i].scale = val; } } else if (i == 5) { /* delete old point */ for (--Nscale; di < Nscale; di++) Scale[di] = Scale[di+1]; } flipscale(); return(0); } mouseright(window, event) Window window; Event *event; { register int i, nbytes, change, fh, beg, end; char *fp, *bp, fbuf[128]; uchar buf[BPP]; change = 0; i = (int) menu_show(b3mp, window, event, 0); switch(i) { case PLAY: if (close(open(SEQFILE, 0)) < 0) { if ((fh = creat(SEQFILE, 0644)) < 0) { perror(SEQFILE); break; } else { buf[0] = 0; buf[1] = 0x90 | Chan; buf[2] = i; buf[3] = 0x40; buf[4] = 24; buf[5] = i; buf[6] = 0; for (i = 36; i < 97; i++) { buf[2] = buf[5] = i; write(fh, buf, 7); } close(fh); } } sprintf(buf, "play %s", SEQFILE); system(buf); break; case DUMP: if ((i = creat(WDRFILE, 0644)) < 0) { perror(WDRFILE); break; } buf[0] = SX_CMD; buf[1] = ID_ENSONIQ; buf[2] = ID_MIRAGE; buf[3] = MIR_SXF_REQ_WAVE; buf[4] = SX_EOB; write(i, buf, 5); close(i); strcpy(Oldfile, "/tmp/qwe.dmp"); sprintf(buf, "sxmpu <%s -r >%s", WDRFILE, Oldfile); system(buf); readdata(Oldfile); upmisc(); change++; break; case LOAD: if ((i = creat(TMPFILE, 0644)) < 0) { perror(TMPFILE); break; } writedata(i); close(i); sprintf(buf, "sxmpu <%s", TMPFILE); system(buf); fprintf(stderr, "\"%s\" written & sent\n", TMPFILE); break; case ROTL: nbytes = BPP * Pcnt; for (i = 0; i < Ramt; i++) buf[i] = Data[i]; for (i = Ramt; i < nbytes; i++) Data[i - Ramt] = Data[i]; for (i = 0; i < Ramt; i++) Data[nbytes - Ramt + i] = buf[i]; change++; break; case ROTR: nbytes = BPP * Pcnt; for (i = 0; i < Ramt; i++) buf[i] = Data[nbytes - Ramt + i]; for (i = nbytes; --i >= Ramt; ) Data[i] = Data[i - Ramt]; for (i = 0; i < Ramt; i++) Data[i] = buf[i]; change++; break; case TRIM: nbytes = BPP * Pcnt; for (beg = 0; beg < nbytes && Data[beg] == 0x80; beg++); for (end = nbytes; --end > beg && Data[end] == 0x80; ); if (beg > 0) for (i = beg; i < nbytes; i++) Data[i - beg] = Data[i]; Pcnt = (end - beg + BPP - 1) / BPP; upmisc(); change++; break; case SCALE: nbytes = BPP * Pcnt; if (Nscale < 1) break; if (Nscale == 1) { for (i = nbytes; --i >= 0; ) { if (Data[i] != 0) Data[i] = (Data[i] * Scale[0].scale + 127) >> 8; } } else { int lb, hb, ls, hs, b, q; for (i = 1; i < Nscale; i++) { lb = Scale[i-1].bpos; if (lb >= nbytes) break; ls = Scale[i-1].scale; hb = Scale[i].bpos; if (hb > nbytes) hb = nbytes; hs = Scale[i].scale; for (b = lb; b++ < hb; ) { if (Data[b] != 0) { q = D_TO_NUM(Data[b]); q = (q * (ls * (hb - b) + hs * (b - lb))); q = q / (hb - lb); q = (q + 128) >> 8; q = NUM_TO_D(q); Data[b] = q < 0? 1 : (q > 0xFF? 0xFF : q); } } } } change++; break; case NORMALIZE: nbytes = BPP * Pcnt; { int minv, maxv, den, q; minv = maxv = 0x80; for (i = nbytes; --i >= 0; ) { if (Data[i]) { if (Data[i] < minv) minv = Data[i]; else if (Data[i] > maxv) maxv = Data[i]; } } minv = 0x80 - minv; maxv = maxv - 0x80; den = maxv > minv? maxv : minv; /****/fprintf(stderr, "scaling=%g\n", (float) 0x7F / den); if (den < 0x7F) { for (i = nbytes; --i >= 0; ) { if (Data[i] != 0) { q = D_TO_NUM(Data[i]); Data[i] = NUM_TO_D((q * 0x7F) / den); } } change++; } } break; case READ: printf("Filename? [%s] ", Oldfile); if (fgets(fbuf, sizeof fbuf, stdin)) { if (*fbuf && *fbuf != '\n') { for (fp = Oldfile, bp = fbuf; (*fp = *bp++) > ' '; fp++); *fp = '\0'; } readdata(Oldfile); upmisc(); change++; } break; case WRITE: if ((i = creat(OUTFILE, 0644)) < 0) perror(OUTFILE); else { writedata(i); close(i); fprintf(stderr, "\"%s\" written\n", OUTFILE); } break; case READDSC: printf("Filename? [%s] ", Oldfile); if (fgets(fbuf, sizeof fbuf, stdin)) { if (*fbuf && *fbuf != '\n') { for (fp = Oldfile, bp = fbuf; (*fp = *bp++) > ' '; fp++); *fp = '\0'; } readdsc(Oldfile); upmisc(); change++; } break; case WRITEDSC: if ((i = creat(OUTFILE, 0644)) < 0) perror(OUTFILE); else { writedsc(i); close(i); fprintf(stderr, "\"%s\" written in dsc format\n", OUTFILE); } break; case QUIT: quit(); break; } return(change); } readdata(file) char *file; { register int i, j, nbytes; FILE *ifp; if (file && *file) { if ((ifp = sopen(file, "r")) == NULL) { perror(file); return(0); } } else { ifp = 0; sprintf(Oldfile, "BLANK"); } while (ifp) { /* find wavedata */ while ((i = fgetc(ifp)) != EOF && i != SX_CMD); if (i != SX_CMD) { fprintf(stderr, "no wavedata found in %s\n", file); exit(1); } if (fgetc(ifp) == ID_ENSONIQ && fgetc(ifp) == ID_MIRAGE && fgetc(ifp) == MIR_SXF_DAT_WAVE) break; } if (ifp) { Pcnt = fgetc(ifp); Pcnt += fgetc(ifp) << 4; } else Pcnt = 16; if (Pcnt <= 0 || Pcnt > 256) { fprintf(stderr, "Weird page count; %d\n", Pcnt); exit(1); } nbytes = BPP * Pcnt; Data = (uchar *) sbrk(nbytes); if ((int) Data == -1) { fprintf(stderr, "sbrk(%d) failed\n", nbytes); exit(3); } for (i = 0; i < nbytes; i++) { if (ifp) { j = fgetc(ifp); j += fgetc(ifp) << 4; } else j = 0x80; Data[i] = j; } if (ifp) fclose(ifp); Ppp = VIEWWIDTH / Pcnt; return(1); } writedata(fh) { register uchar *dp, *bp; register int csum; uchar buf[2 * BPP]; int p, i; csum = 0; buf[0] = RT_RESET; buf[1] = SX_CMD; buf[2] = ID_ENSONIQ; buf[3] = ID_MIRAGE; buf[4] = MIR_SXF_DAT_WAVE; buf[5] = (Pcnt & 0x0F); buf[6] = (Pcnt >> 4); csum = buf[5] + buf[6]; write(fh, buf, 7); dp = Data; for (p = 0; p < Pcnt; p++) { bp = buf; for (i = 0; i < BPP; i++) { *bp = (*dp & 0x0F); csum += *bp++; *bp = (*dp++ & 0xF0) >> 4; csum += *bp++; } write(fh, buf, 512); csum &= 0x7F; } buf[0] = (csum & 0x7F); buf[1] = 0xF7; write(fh, buf, 2); } readdsc(file) char *file; { register int i, j, k, nbytes; char c; long rnbytes; struct stat statb; FILE *ifp; if (file && *file) { if ((ifp = sopen(file, "r")) == NULL) { perror(file); return(0); } } else return(readdata(0)); j = getc(ifp); k = getc(ifp); if (((k << 8) | j) != DSCMAGIC) { fprintf(stderr, "%s is not a DSC file\n", file); return(0); } if (fstat(fileno(ifp), &statb) < 0) { perror(file); return(0); } rnbytes = (statb.st_size - 2) / 2; /* ignore half of them 16->8 */ Pcnt = (rnbytes + BPP - 1) / BPP; if (Pcnt <= 0 || Pcnt > 256) { fprintf(stderr, "weird size; %d (pages)\n", Pcnt); exit(1); } nbytes = BPP * Pcnt; Data = (uchar *) sbrk(nbytes); if ((int) Data == -1) { fprintf(stderr, "sbrk(%d) failed\n", nbytes); exit(3); } for (i = 0; i < nbytes; i++) { if (ifp) { j = fgetc(ifp); k = fgetc(ifp); if (j == EOF || k == EOF) { fclose(ifp); ifp = 0; j = 0x80; } else { c = k; /* extend sign */ j = c + ((j & 0x80)? 1 : 0); /* half adjust */ j += 0x80; /* move 0 to 0x80 */ } } else j = 0x80; Data[i] = j; } if (ifp) fclose(ifp); Ppp = VIEWWIDTH / Pcnt; return(1); } writedsc(fh) { register uchar *dp, *bp; register int csum; uchar buf[2 * BPP]; int p, i; buf[0] = (DSCMAGIC & 0xFF); buf[1] = (DSCMAGIC >> 8); write(fh, buf, 2); dp = Data; for (p = 0; p < Pcnt; p++) { bp = buf; for (i = 0; i < BPP; i++) { *bp++ = 0; *bp++ = *dp++ - 0x80; /* move 0x80 to 0 */ } write(fh, buf, bp - buf); } } quit() { while (ready_cursor()); exit(0); /*NOTREACHED*/ }