majka@ubc-vision.UUCP (03/03/87)
- - - CUT - - - CUT - - - CUT - - - CUT - - - CUT - - - CUT - - - CUT - - - #!/bin/sh # # shell archive - extract with /bin/sh # echo extracting file README sed 's/^X//' > README <<'!FUNKY!STUFF!' XThis package contains a program called movie, which is a realtime Xplayback program for a set of SUN rasterfiles. The code works on Xboth SUN-2 and SUN-3 bitmap displays. It is something like framedemo, Xbut it uses rasterfile(5) files. IT DOES NOT RUN UNDER SUN WINDOWS. XSUNwindows does not provide enough control of the screen or enough Xspeed to do this kind of stuff. It provides single frame, forward Xand backward loops with variable speed, mouse-stepped playback, and Xother miscellaneous features. X XI think the code is reasonable, It tries to avoid magic as much as Xpossible. I must warn you, however, that the whole thing was written Xin a week, and there may be a few ugly and/or mysterious sections. XI'm sending it out because I probably won't be adding much more to it, Xor spending much time cleaning it up. X XIncluded are a makefile and a manual. X XHappy Graphics! X X--- XMarc Majka - UBC Laboratory for Computational Vision !FUNKY!STUFF! echo extracting file Makefile sed 's/^X//' > Makefile <<'!FUNKY!STUFF!' X# Makefile for movie X XBIN=movie XPIX=-lpixrect X Xmovie: movie.c X cc -o ${BIN}/movie movie.c ${PIX} !FUNKY!STUFF! echo extracting file movie.c sed 's/^X//' > movie.c <<'!FUNKY!STUFF!' X#include <pixrect/pixrect_hs.h> X#include <stdio.h> X#include <sgtty.h> X#include <fcntl.h> X#include <sys/time.h> X X#define NULLPR (struct pixrect *)NULL X Xstruct pixrect *screen; Xstruct pixfont *pf_default(), *pfont; X Xint oldr, oldc, row, col, oldx, oldy, sx, sy, ix, iy, go; Xint oldm, mrow, oldmy, my, imy, page, px, oldpx, pc, oldpc; Xint bl, bc, br; Xint MouseFD; Xstruct pr_prpos xywh; Xint (*Button[4])(); Xint (*MenuFunction[16][32])(); X XFILE *mouse; X X#define LEFT 1 X#define CENTRE 2 X#define RIGHT 4 X#define L 1 X#define C 2 X#define R 3 X#define MenuX1 910 X#define MenuY1 60 X#define MenuY2 764 X#define MenuWidth 240 X#define MenuHeight 22 X#define MenuPages 16 X#define MenuRows 32 X#define LastMenuY MenuY2 - MenuHeight X X#define PageP1 MenuX1 X#define PageWidth 30 X#define PageP2 PageP1 + PageWidth X#define PageEnd PageP2 + PageWidth X X#define MLineX 910 X#define MLineY 30 X#define MLWidth 80 X X#define PIX_XOR (PIX_SRC|PIX_DST)&PIX_NOT(PIX_SRC&PIX_DST) X#define MAXFRAMES 100 Xstruct pixrect *movie[MAXFRAMES]; Xint nframe, lastframe, frame, rolling, screenframe, framerate; Xstruct timeval delay; Xint delaytab_s[201], delaytab_us[201]; Xint framex, framey, frameop; X Xchar menu[MenuPages][MenuRows+1][128], MouseString[4][11]; Xint MainX1, MainY1, MainX2, MainY2; X Xchar scriptfile[256]; X Xmain(argc,argv) Xint argc; Xchar *argv[]; X{ X int argn; X X scriptfile[0] == '\0'; X X for (argn = 1; argn < argc; argn++) { X if (argv[argn][0] == '-') { X switch (argv[argn][1]) { X case 'p': /* frame position */ X framey = atoi(argv[++argn]); X framex = atoi(argv[++argn]); X break; X case 's': /* script */ X strcpy(scriptfile,argv[++argn]); X break; X default: X Usage(); X exit(0); X } X } X else { X Usage(); X exit(0); X } X } X X Init(); X Menu(); X Fini(); X} X XUsage() X{ X fprintf(stderr,"movie [-p %%d %%d] [-s %%s]\n"); X fprintf(stderr," -p Frame row col position\n"); X fprintf(stderr," -s Script file name\n"); X} X XMenu() X{ X int dx, dy, but; X X DrawMenuCursor(px,my); X X while (go) { X ReadMouse(&dx,&dy,&but); X MoveMenuCursor(dx,dy); X if (but) MenuHandle(my,but); X } X X DrawMenuCursor(px,my); X} X XMoveMenuCursor(dx,dy) Xint dx,dy; X{ X oldm = mrow; X oldmy = my; X oldpc = pc; X oldpx = px; X imy -= dy; X px += dx; X if (imy < MenuY1) imy = MenuY1; X if (imy > MenuY2) imy = MenuY2; X if (px < PageP1) px = PageP1; X if (px > PageEnd) px = PageEnd; X X mrow = 1 + (imy - MenuY1) / MenuHeight; X my = MenuY1 + (mrow - 1) * MenuHeight; X pc = (px > PageP2); X X if (oldm != mrow || oldpc != pc) { X DrawMenuCursor(oldpx,oldmy); X DrawMenuCursor(px,my); X } X} X XDrawMenuCursor(x,y) Xint x,y; X{ X int r; X X r = (y - MenuY1) / MenuHeight; X X if (y > LastMenuY) { X if (x > PageP2) pr_rop(screen,PageP2,y,PageWidth,MenuHeight, X PIX_NOT(PIX_DST),NULLPR,0,0); X else pr_rop(screen,PageP1,y,PageWidth,MenuHeight, X PIX_NOT(PIX_DST),NULLPR,0,0); X } X else { X pr_rop(screen,MenuX1,y,MenuWidth-1,MenuHeight, X PIX_NOT(PIX_DST),NULLPR,0,0); X X if (menu[page][r][0] == '\0') X pr_rop(screen,MenuX1+3,y+3,MenuWidth-7,MenuHeight-6, X PIX_NOT(PIX_DST),NULLPR,0,0); X } X} X XBindButton(b,str,f) Xint b; Xchar *str; Xint (*f)(); X{ X Button[b] = f; X MouseLine(b,str); X} X XBOGUS() X{ X} X XMouseLine(b,str) Xint b; Xchar *str; X{ X MouseString[b][0] = ' '; X strncpy(MouseString[b]+1,str,8); X MouseString[b][9] = ' '; X MouseString[b][10] = '\0'; X DrawMouseItem(b); X} X XRefreshMouseLine() X{ X struct pr_prpos wh; X X wh.pr = screen; X wh.pos.x = MLineX; X wh.pos.y = MLineY + MenuHeight - 3; X pr_rop(screen,wh.pos.x,wh.pos.y-14,MenuWidth+1,19,PIX_CLR,NULLPR,0,0); X wh.pos.x += 8; X wh.pos.y -= 3; X pf_text(wh,PIX_NOT(PIX_SRC),pfont," left "); X wh.pos.x += MLWidth; X pf_text(wh,PIX_NOT(PIX_SRC),pfont," centre "); X wh.pos.x += MLWidth; X pf_text(wh,PIX_NOT(PIX_SRC),pfont," right "); X X DrawMouseItem(L); X DrawMouseItem(C); X DrawMouseItem(R); X} X XDrawMouseItem(b) Xint b; X{ X struct pr_prpos wh; X X wh.pr = screen; X wh.pos.x = MLineX + (b - 1) * MLWidth; X wh.pos.y = MLineY; X pr_rop(screen,wh.pos.x,wh.pos.y-14,MLWidth+1,19,PIX_CLR,NULLPR,0,0); X pf_text(wh,PIX_SRC,pfont,MouseString[b]); X} X XInit() X{ X FILE *fopen(); X int one = 1; X int BOGUS(), Menu(); X int i, s, us; X double d, dd, ds, dus; X X LoadFrames(); X screen = pr_open("/dev/fb"); X mouse = fopen("/dev/mouse","r"); X if (mouse == NULL) { X (void)printf("can't open /dev/mouse\n"); X exit(1); X } X MouseFD = fileno(mouse); X X go = 1; X framerate = 90; X screenframe = -1; X frame = 0; X framex = 0; X framey = 0; X frameop = PIX_SRC; X X delaytab_s [ 0] = delaytab_s [200] = 0; X delaytab_us[ 0] = delaytab_us[200] = 0; X d = 0.75; X dd = d / 99.0; X X for (i = 1; i < 100; i++) { X s = (int)d; X dus = (d - (double)s) * 100000.0; X us = (int)dus; X delaytab_s[i + 100] = delaytab_s[100 - i] = s; X delaytab_us[i + 100] = delaytab_us[100 - i] = us; X d -= dd; X } X X MainX1 = 0; X MainY1 = 0; X MainX2 = 899; X MainY2 = 899; X imy = MenuY1; X my = MenuY1; X mrow = 1; X px = PageP1; X pc = 0; X X xywh.pr = screen; X xywh.pos.x = 910; X xywh.pos.y = 10; X X page = 1; X X pfont = pf_default(); X EraseScreen(); X InitMenu(); X page = 0; X RefreshMenu(); X DisplayFrame(); X Button[0] = BOGUS; X BindButton(L,"Select",BOGUS); X BindButton(C," ",BOGUS); X BindButton(R," ",BOGUS); X RefreshMouseLine(); X} X XLoadFrames() X{ X int ifile; X char str[256]; X FILE *fp, *fopen(), *script; X struct pixrect *pr_load(); X struct colormap_t *cmap; X X fprintf(stderr,"Loading frames\n"); X X if (scriptfile[0] == '\0') { X ifile = 1; X X for (frame = 0; frame < MAXFRAMES && ifile; frame++) { X sprintf(str,"frame.%d",frame); X fp = fopen(str,"r"); X if (fp == NULL) ifile = 0; X else { X movie[frame] = pr_load(fp,cmap); X fclose(fp); X fprintf(stderr,"%2d ",frame); X if (9 == (frame % 10)) fprintf(stderr,"\n"); X fflush(stderr); X } X } X } X else { X script = fopen(scriptfile,"r"); X if (script == NULL) { X fprintf(stderr,"movie: can't read script file \"%s\"\n",scriptfile); X exit(1); X } X X frame = 0; X while (EOF != fscanf(script,"%s",str)) { X fp = fopen(str,"r"); X if (fp == NULL) { X fprintf(stderr,"movie: can't read frame file \"%s\"\n",str); X exit(1); X } X movie[frame] = pr_load(fp,cmap); X fclose(fp); X fprintf(stderr,"frame %d: %s\n",frame,str); X frame++; X } X frame++; /* overshoot like above */ X } X X fprintf(stderr,"\n"); X nframe = frame - 1; X lastframe = frame - 2; X frame = 0; X if (nframe == 0) Fini(); X} X XFini() X{ X EraseScreen(); X (void)fclose(mouse); X exit(0); X} X XRefreshMenu() X{ X struct pr_prpos wh; X int r; X char pn[64]; X X wh.pr = screen; X wh.pos.x = MenuX1 + 3; X EraseMenu(); X/* X pr_vector(screen,900,0,900,900,PIX_CLR,0); X pr_vector(screen,901,0,901,900,PIX_CLR,0); X pr_vector(screen,902,0,902,900,PIX_CLR,0); X*/ X wh.pos.y = MenuY1 + 14; X for (r = 0; r < MenuRows; r++) { X pf_text(wh,PIX_SRC,pfont,menu[page][r]); X wh.pos.y += MenuHeight; X } X pf_text(wh,PIX_SRC,pfont," + "); X wh.pos.x += PageWidth; X pf_text(wh,PIX_SRC,pfont," - "); X wh.pos.x += PageWidth; X sprintf(pn,"%2d %s",page,menu[page][MenuRows]); X pf_text(wh,PIX_NOT(PIX_SRC),pfont,pn); X} X XEraseMenu() X{ X pr_rop(screen,MenuX1,MenuY1,MenuWidth,MenuY2,PIX_SET,NULLPR,0,0); X} X X XReadMouse(x,y,b) Xint *x,*y,*b; X{ X char mbuf[4]; X int ms, dx, dy, ol, oc, or, gotany, bits; X X *x = 0; X *y = 0; X *b = 0; X X bits = (1 << MouseFD); X gotany = select(16,&bits,(int *)0,(int *)0,&delay); X X if (bits & (1 << MouseFD)) { X read(MouseFD,mbuf,3); X X ms = mbuf[0]; X dx = mbuf[1]; X dy = mbuf[2]; X *x = dx; X *y = dy; X ol = bl; X oc = bc; X or = br; X bl = 4 & ~ms; X bc = 2 & ~ms; X br = 1 & ~ms; X *b = 0; X if (bl && !ol) *b = 1; X if (bc && !oc) *b = 2; X if (br && !or) *b = 3; X } X} X XMenuHandle(y,b) Xint y,b; X{ X int r,oldp; X X r = (y - MenuY1) / MenuHeight; X X if (r == MenuRows) { X oldp = page; X if (px > PageP2 && page > 0) page--; X else if (px < PageP2 && page < (MenuPages - 1)) page++; X if (page != oldp) { X DrawMenuCursor(px,my); X RefreshMenu(); X DrawMenuCursor(px,my); X } X } X else if (b == L) ExecMenu(page,r); X} X XExecMenu(page,row) Xint page,row; X{ X (*MenuFunction[page][row])(); X} X XEraseScreen() X{ X pr_rop(screen,0,0,1152,900,PIX_SET,NULLPR,0,0); X} X XRedrawEverything() X{ X EraseScreen(); X RefreshMenu(); X RefreshMouseLine(); X DrawMenuCursor(px,my); X} X XMenuItem(str) Xchar *str; X{ X int mr, mp; X char ms[64]; X X sscanf(str+5,"%d %d %[^\n]",&mp,&mr,ms); X SetMenuItem(mp,mr,ms); X} X XSetMenuItem(p,r,str,ptr) Xint p,r; Xchar *str; Xint (*ptr)(); X{ X char tstr[128]; X int i, l, mc; X X mc = (MenuWidth / 8) - 1; X X strcpy(tstr," "); X strcat(tstr,str); X l = strlen(tstr); X if (l < mc) for (i = l; i < mc; i++) strcat(tstr," "); X if (l > mc) tstr[mc-1] = ' '; X strncpy(menu[p][r],tstr,mc); X MenuFunction[p][r] = ptr; X X if (p == page) { X DrawMenuCursor(px,my); X RefreshMenu(); X DrawMenuCursor(px,my); X } X} X XInitMenu() X{ X int p, r, m; X int BOGUS(), M_quit(); X int DisplayFirstFrame(), DisplayNextFrame(); X int DisplayPrevFrame(), DisplayLastFrame(), SingleFrame(); X int ForwardLoop(), BackwardLoop(), VariableLoop(); X int BackAndForth(), PositionFrame(), ReverseVideo(); X int ForwardPlay(), BackwardPlay(), ScrollFrames(); X X for (p = 0; p < MenuPages; p++) X for (r = 0; r <= MenuRows; r++) { X strcpy(menu[p][r],""); X MenuFunction[p][r] = BOGUS; X } X X m = 0; X X SetMenuItem(0,m++,"First Frame",DisplayFirstFrame); X SetMenuItem(0,m++,"Forward Frame",DisplayNextFrame); X SetMenuItem(0,m++,"Backward Frame",DisplayPrevFrame); X SetMenuItem(0,m++,"Last Frame",DisplayLastFrame); X SetMenuItem(0,m++,"Single Frame",SingleFrame); X SetMenuItem(0,m++,"Forward Play Once",ForwardPlay); X SetMenuItem(0,m++,"Backward Play Once",BackwardPlay); X SetMenuItem(0,m++,"Forward Loop",ForwardLoop); X SetMenuItem(0,m++,"Backward Loop",BackwardLoop); X SetMenuItem(0,m++,"Back and Forth Loop",BackAndForth); X SetMenuItem(0,m++,"Variable Speed Loop",VariableLoop); X SetMenuItem(0,m++,"Scroll With Mouse",ScrollFrames); X SetMenuItem(0,m++,"Position Frame",PositionFrame); X SetMenuItem(0,m++,"Reverse Frame Video",ReverseVideo); X SetMenuItem(0,m++,"Quit",M_quit); X} X XM_quit() X{ X go = 0; X} X XDisplayFirstFrame() X{ X frame = 0; X DisplayFrame(); X} X XDisplayNextFrame() X{ X if (frame < lastframe) { X frame++; X DisplayFrame(); X } X} X XDisplayPrevFrame() X{ X if (frame > 0) { X frame--; X DisplayFrame(); X } X} X XDisplayLastFrame() X{ X frame = lastframe; X DisplayFrame(); X} X XSingleFrame() X{ X int dx, dy, but, Cut(), DisplayPrevFrame(), DisplayNextFrame(); X X BindButton(L,"Backward",DisplayPrevFrame); X BindButton(C,"Stop",Cut); X BindButton(R,"Forward",DisplayNextFrame); X X rolling = 1; X while (rolling) { X ReadMouse(&dx,&dy,&but); X (*Button[but])(); X } X X BindButton(L,"Select",BOGUS); X BindButton(C," ",BOGUS); X BindButton(R," ",BOGUS); X} X XForwardPlay() X{ X if (framerate < 0) framerate *= -1; X X for (frame = 0; frame < nframe; frame++) { X if (framerate < 0) framerate = 0; X DisplayFrame(); X DelayFrame(); X } X frame = lastframe; X} X XBackwardPlay() X{ X if (framerate > 0) framerate *= -1; X X for (frame = lastframe; frame >= 0; frame--) { X if (framerate > 0) framerate = 0; X DisplayFrame(); X DelayFrame(); X } X frame = 0; X} X XForwardLoop() X{ X int IncreaseRate(), DecreaseRate(), Cut(), dx, dy, but; X X BindButton(L,"Slower",DecreaseRate); X BindButton(C,"Stop",Cut); X BindButton(R,"Faster",IncreaseRate); X X if (framerate < 0) framerate *= -1; X X rolling = 1; X frame = 0; X X while (rolling) { X DisplayFrame(); X ReadMouse(&dx,&dy,&but); X (*Button[but])(); X DelayFrame(); X if (framerate < 0) framerate = 0; X if (framerate != 0) frame = (frame + 1) % nframe; X } X frame = lastframe; X BindButton(L,"Select",BOGUS); X BindButton(C," ",BOGUS); X BindButton(R," ",BOGUS); X} X XBackwardLoop() X{ X int IncreaseRate(), DecreaseRate(), Cut(), dx, dy, but; X X BindButton(L,"Slower",DecreaseRate); X BindButton(C,"Stop",Cut); X BindButton(R,"Faster",IncreaseRate); X X if (framerate > 0) framerate *= -1; X X rolling = 1; X frame = 0; X X while (rolling) { X DisplayFrame(); X ReadMouse(&dx,&dy,&but); X (*Button[but])(); X DelayFrame(); X if (framerate > 0) framerate = 0; X if (framerate != 0) frame = (frame + lastframe) % nframe; X } X frame = lastframe; X BindButton(L,"Select",BOGUS); X BindButton(C," ",BOGUS); X BindButton(R," ",BOGUS); X} X XVariableLoop() X{ X int IncreaseRate(), DecreaseRate(), Cut(), dx, dy, but; X X BindButton(L,"Slower",DecreaseRate); X BindButton(C,"Stop",Cut); X BindButton(R,"Faster",IncreaseRate); X X rolling = 1; X frame = 0; X X while (rolling) { X DisplayFrame(); X ReadMouse(&dx,&dy,&but); X framerate += dy; X if (framerate > 100) framerate = 100; X if (framerate < -100) framerate = -100; X (*Button[but])(); X DelayFrame(); X if (framerate > 0) frame = (frame + 1) % nframe; X else if (framerate < 0) frame = (frame + lastframe) % nframe; X } X X X BindButton(L,"Select",BOGUS); X BindButton(C," ",BOGUS); X BindButton(R," ",BOGUS); X} X XBackAndForth() X{ X int IncreaseRate(), DecreaseRate(), Cut(), dx, dy, but, dir; X X BindButton(L,"Slower",DecreaseRate); X BindButton(C,"Stop",Cut); X BindButton(R,"Faster",IncreaseRate); X X if (framerate < 0) framerate *= -1; X X rolling = 1; X frame = 0; X dir = 0; X X while (rolling) { X DisplayFrame(); X ReadMouse(&dx,&dy,&but); X (*Button[but])(); X DelayFrame(); X if (framerate < 0) framerate = 0; X if (framerate != 0) { X if (dir) { X if (frame == lastframe) { X dir = !dir; X frame--; X } X else frame++; X } X else { X if (frame == 0) { X dir = !dir; X frame++; X } X else frame--; X } X } X } X X BindButton(L,"Select",BOGUS); X BindButton(C," ",BOGUS); X BindButton(R," ",BOGUS); X} X XScrollFrames() X{ X int dx, dy, but, x, Cut(); X X BindButton(L,"Stop",Cut); X X x = frame * 8; X rolling = 1; X X while (rolling) { X DisplayFrame(); X ReadMouse(&dx,&dy,&but); X (*Button[but])(); X X x += dx; X frame = x / 8; X if (frame > lastframe) { X frame = lastframe; X x = frame * 8; X } X if (frame < 0) { X frame = 0; X x = 0; X } X } X BindButton(L,"Select",BOGUS); X} X XIncreaseRate() X{ X if (framerate < 100) framerate += 1; X} X XDecreaseRate() X{ X if (framerate > -100) framerate -= 1; X} X XCut() X{ X rolling = 0; X} X XDisplayFrame() X{ X Annotation(); X X if (frame == screenframe) return(0); X X screenframe = frame; X X pr_rop(screen,framex,framey, X movie[frame]->pr_size.x,movie[frame]->pr_size.y, X frameop,movie[frame],0,0); X} X XAnnotation() X{ X char str[256]; X X sprintf(str,"Frame %2d of %d %4d",frame,lastframe,framerate); X pf_text(xywh,PIX_NOT(PIX_SRC),pfont,str); X} X XDelayFrame() X{ X int f, bits, gotsome; X char mbuf[3]; X X bits = 1 << MouseFD; X X f = framerate + 100; X delay.tv_sec = delaytab_s[f]; X delay.tv_usec = delaytab_us[f]; X gotsome = select(32,&bits,(int *)0,(int *)0,&delay); X if (gotsome < 0) { X perror("select"); X fprintf(stderr,"returned value was %d\n",gotsome); X DieHorribly(); X } X if (bits & (1 << MouseFD)) { X read(MouseFD,mbuf,3); X framerate += mbuf[2]; X if (framerate > 100) framerate = 100; X if (framerate < -100) framerate = -100; X delay.tv_sec = 0; X delay.tv_usec /= 2; X select(32,(int *)0,(int *)0,(int *)0,&delay); X } X} X XDieHorribly() X{ X char str[128]; X X sprintf(str," Goodbye Cruel World! "); X pf_text(xywh,PIX_SRC,pfont,str); X X exit(1); X} X XPositionFrame() X{ X int dx, dy, but, Cut(), maxx, maxy, oldx, oldy, xs, ys; X X BindButton(L,"Stop",Cut); X rolling = 1; X X xs = movie[frame]->pr_size.x; X ys = movie[frame]->pr_size.y; X X maxx = 899 - xs; X maxy = 899 - ys; X X DrawBox(framex,framey,xs,ys); X X while (rolling) { X ReadMouse(&dx,&dy,&but); X (*Button[but])(); X oldx = framex; X oldy = framey; X framex += dx; X framey -= dy; X if (framex < 0) framex = 0; X if (framey < 0) framey = 0; X if (framex > maxx) framex = maxx; X if (framey > maxy) framey = maxy; X if (oldx != framex || oldy != framey) { X DrawBox(oldx,oldy,xs,ys); X DrawBox(framex,framey,xs,ys); X } X } X EraseFrame(); X DisplayFrame(); X BindButton(L,"Select",BOGUS); X} X XReverseVideo() X{ X if (frameop == PIX_SRC) frameop = PIX_NOT(PIX_SRC); X else frameop = PIX_SRC; X EraseFrame(); X DisplayFrame(); X} X XEraseFrame() X{ X screenframe = -1; X pr_rop(screen,0,0,900,900,PIX_SET,NULLPR,0,0); X} X XDrawBox(x,y,w,h) Xint x,y,w,h; X{ X int x2, y2; X X x2 = x + w - 1; X y2 = y + h - 1; X X pr_vector(screen,x,y,x2-1,y,PIX_NOT(PIX_DST),0); X pr_vector(screen,x2,y,x2,y2-1,PIX_NOT(PIX_DST),0); X pr_vector(screen,x2,y2,x+1,y2,PIX_NOT(PIX_DST),0); X pr_vector(screen,x,y2,x,y+1,PIX_NOT(PIX_DST),0); X} X XTouch(f,i) Xint f,i; X{ X int pix; X X if (i > 0) { X if (f < lastframe) pix = pr_get(movie[f+i],0,0); X else pix = pr_get(movie[0],0,0); X } X else { X if (f > 0) pix = pr_get(movie[f+i],0,0); X else pix = pr_get(movie[lastframe],0,0); X } X} !FUNKY!STUFF! echo extracting file movie.1 sed 's/^X//' > movie.1 <<'!FUNKY!STUFF!' X.TH MOVIE 1 X.SH NAME Xmovie - realtime playback of SUN rasterfiles X.SH SYNOPSIS X.B movie X[-p r c] [-s file] X.SH DESCRIPTION X.B movie Xreads a set of rasterfiles (see X.I rasterfile(5)\fR) Xand stores them in memory. It provides a number of functions for Xanimating the sequence of rasters on the SUN bitmap display. These Xfunctions are described in the X.B Playback Functions Xsection below. X.sp X.B movie X.I does not Xrun under SUN-Windows. It uses the mouse for frame and speed control, Xas well as menu selection of playback functions. X.sp XThe screen is divided into 5 areas. The left square part of the screen X(900 * 900 pixels) is the frame area. All rasters are displayed here. XThe right part of the screen comprises a single information line at the Xtop of the screen, a mouse button line, a menu area, and a menu page Xselection area. X.sp XThe information line displays the currently displayed frame number, Xthe number of the last frame, and a speed indicator. The speed Xcontrols the frame presentation rate during playback. The speed is Xshown as a number between 0 and 100. A speed of 0 indicates no motion. XA speed of 100 indicates the maximum possible redisplay rate. When Xframes are being presented in reverse sequence, as in a X.B Backward Loop, Xthe speed is shown as a negative number. X.sp XThe mouse button line shows the status of the three mouse buttons. XThe line is divided into 3 areas, corresponding to the left, Xcentre, and right mouse buttons. The effect of pressing one of Xthe buttons is indicated in the appropriate area. X.sp XThe menu is displayed below the mouse button line. Each menu Xitem is shown in a reverse video line. The menu cursor moves Xup and down through the menu, and reverses the bits in the line Xunder the cursor. X.sp XThe menu page selection area is at the bottom of the menu. It has Xtwo areas, labeled \*(lq+\*(rq and \*(lq-\*(rq, which will switch to the next Xor previous menu page. This feature unnecessary for X.B movie, Xas only the first menu page has any \*(lqlive\*(rq entries, but is Xthere for future expansion. The menu contains 16 pages, each Xof 32 menu items. The current page number is displayed to Xthe right of the \*(lq-\*(rq selector. X.sp XMouse motion is up/down to select menu items. Playback functions Xgenerally take up/down motions to cause increase/decrease in playback Xspeed, and left/right motions to indicate previous/next frame selection. X.sp XThe position of the upper left corner of displayed frames may be Xset by the command line X.B -p Xoption. The following two integers are taken as row and column offsets. X.sp XBy default X.B movie Xwill read rasterfiles from the current directory. Files with names of the Xform X.I frame.# X(where # is a number) are read into memory. The files must be numbered Xsequentially, beginning with frame.0. This is similar to the convention Xused by the SUN demo program X.B framedemo, Xbut note that in this case the files are in X.I rasterfile Xformat. XThe X.B -s Xoption overrides the reading of the \*(lqframe.#\*(rq files. The argument Xfollowing the X.B -s Xoption indicates a file to be read, which contains a list of Xrasterfiles to read in sequence. X.SH "PLAYBACK FUNCTIONS" X.B First Frame X.br XDisplays the first frame X.sp X.B Next Frame X.br XDisplays the next frame in the sequence, without wrap-around. X.sp X.B Previous Frame X.br XDisplays the previous frame in the sequence, without wrap-around. X.sp X.B Last Frame X.br XDisplays the last frame in the sequence. X.sp X.B Single Frame X.br XSingle frame playback. The left and right mouse Xbuttons select the previous and next frames. X.sp X.B Forward Play Once X.br XPlays the sequence from first to last frame once, at the current Xframe speed. X.sp X.B Backward Play Once X.br XPlays the sequence from last to first frame once, at the current Xframe speed. X.sp X.B Forward Loop X.br XPlay the sequence continually, from first to last frame. The Xplayback speed may be adjusted with up/down mouse motion, or Xwith the left and right mouse buttons. X.sp X.B Backward Loop X.br XPlay the sequence continually, from last to first frame. The Xplayback speed may be adjusted with up/down mouse motion, or Xwith the left and right mouse buttons. X.sp X.B Back and Forth Loop X.br XPlay the sequence continually, from first to last, then last to first Xframe. The playback speed may be adjusted with up/down mouse motion, or Xwith the left and right mouse buttons. X.sp X.B Variable Speed Loop X.br XPlay the sequence continually, The Xplayback speed may be adjusted with up/down mouse motion, or Xwith the left and right mouse buttons. The playback direction Xmay be changed by moving the speed through 0. Negative Xspeed indicates reverse playback. X.sp X.B Scroll With Mouse X.br XFrames are displayed one at a time. Left/right mouse motion displays Xprevious/next frames. X.sp X.B Position Frame X.br XAllows the upper left starting position of displayed frames Xto be adjusted interactively. A box is drawn around the frame, Xand moved within the frame area with mouse motion. Pressing Xthe left mouse button causes frame display to take place at the Xnew position. X.sp X.B Reverse Frame Video X.br XReverses the black/white sense of displayed frames. X.sp X.B Quit X.br XExits the X.B movie Xprogram. X.SH ACKNOWLEDGEMENT XThe playback functions in X.B movie Xare similar to the X.B S-Dynamics Xanimation playback program on our X.B Symbolics 3650. XI thank the authors of that software for giving me the idea Xto write this one. This program is, however, in no way Xcopied or translated from that code. X.SH AUTHOR XMarc Majka !FUNKY!STUFF! echo Done\! exit 0