home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / games / arcade / astropan / panic.c next >
C/C++ Source or Header  |  1988-04-26  |  20KB  |  567 lines

  1. /* AstroPanic ST  by Charles Brannon */
  2. /* adapted from MULTIFDB.C by Charles Brannon */
  3. /* created June 12 1986 */
  4. /* last modified June 27 1986 */
  5.  
  6. #include <define.h>
  7. #include <gemdefs.h>
  8. #include <obdefs.h>
  9. #include <osbind.h>
  10. #include <stdio.h>
  11.  
  12. #define fdb_XOR 6
  13. #define fdb_REPLACE 3
  14. #define fdb_ERASE 4
  15. #define fdb_TRANS 7
  16. #define fdb_REVTRANS 13
  17. #define rnd(x) (Random()%(x))
  18. #define HIDE_MOUSE graf_mouse(M_OFF,&dummy)
  19. #define SHOW_MOUSE graf_mouse(M_ON,&dummy)
  20. #define COLORMODE work_out[35]
  21. #define NUMSPRITES 6
  22. #define MISSILE_H (COLORMODE? 8 : 16)
  23. #define MISSILE_SPEED (COLORMODE? 7 : 12 )
  24. #define TOPSCREEN 4
  25. #define TEXTBOX 32
  26.  
  27. /* global variables */
  28.  
  29.         int dummy,ch,cw;
  30.         int work_handle,contrl[12],pxyarray[10];
  31.         int intin[128],intout[128],ptsin[128],ptsout[128];
  32.         int work_in[11],work_out[57];
  33.  
  34.         struct my_fdb
  35.         {
  36.                 char *fd_addr; /* address of raster */
  37.                 int fd_w; /* width in pixels */
  38.                 int fd_h; /* height in rows */
  39.                 int fd_wdwidth; /* width in words */
  40.                 int fd_stand; /* 0 for ST, 1 for standard */
  41.                 int fd_nplanes; /* how many planes */
  42.                 int fd_r1, fd_r2, fd_r3; /* reserved */
  43.         } saucer,screen,cannon;
  44.  
  45.         int colortab[16][3]; /* used to save colors */
  46.         unsigned long score; /* you know what this is! */
  47.         int ships; /* how many cannons are left */
  48.         int missile; /* flag for whether missile is in flight or not */
  49.         int missile_x,missile_y; /* position of missile in flight */
  50.         int cannon_x, cannon_y; /* horizontal & vertical position of cannon */
  51.         int xborder,yborder; /* screen boundaries */
  52.         int x[NUMSPRITES],y[NUMSPRITES]; /* holds x/y position of sprites */
  53.         int xacc[NUMSPRITES],yacc[NUMSPRITES]; /* acceleration factors */
  54.         int isdead[NUMSPRITES]; /* is this sprite dead? */
  55.         int death_toll; /* saucers shot this round */
  56.         int textline; /* line where text box starts */
  57.         int round; /* current level of game */
  58.         int speed; /* saucer speed */
  59.  
  60. main()
  61. {
  62.         int sprite; /* sprite index */
  63.         int prev_x,prev_y; /* stores previous position of a sprite */
  64.         appl_init();
  65.         init_workstation();
  66.         set_colors();
  67.         HIDE_MOUSE;
  68.         clear_sky();
  69.         form_alert(1,"[1][AstroPanic!|Charles Brannon|(C) 1986 COMPUTE!|][ Let's Play! ]");
  70.         init_shapes();
  71.         xborder=work_out[0]-saucer.fd_w-4;
  72.         textline=work_out[1]-((COLORMODE)? TEXTBOX : TEXTBOX<<1);
  73.         yborder=textline-cannon.fd_h;
  74.         cannon_y=yborder;
  75.         reset_game();
  76.         /* ye olde main loope */
  77.         FOREVER
  78.         {
  79.                 check_for_pause();
  80.                 for (sprite=0;sprite<NUMSPRITES;sprite++)
  81.                 {
  82.                         if (isdead[sprite]) { dumdum(); continue; }
  83.                         prev_x=x[sprite]; prev_y=y[sprite];
  84.                         x[sprite]+=xacc[sprite];
  85.                         y[sprite]+=yacc[sprite];
  86.                         if (x[sprite]<4 || x[sprite]>xborder)
  87.                                 xacc[sprite]=-xacc[sprite],x[sprite]=prev_x;
  88.                         if (y[sprite]<TOPSCREEN || y[sprite]>yborder)
  89.                                 yacc[sprite]=-yacc[sprite],y[sprite]=prev_y;
  90.                         put(&saucer,prev_x,prev_y,fdb_XOR);
  91.                         put(&saucer,x[sprite],y[sprite],fdb_XOR);
  92.                         if (cannon_y-y[sprite]<8)
  93.                                 if ( (cannon_x>=x[sprite] && cannon_x<=x[sprite]+saucer.fd_w) ||
  94.                                         (cannon_x+cannon.fd_w>=x[sprite] && cannon_x+cannon.fd_w<=x[sprite]+saucer.fd_w) )
  95.                                 {
  96.                                         kill_cannon();
  97.                                         break;
  98.                                 }
  99.                 } /* end for */
  100.                 move_cannon();
  101.                 if (missile) update_missile();
  102.         }
  103. }
  104.  
  105. Terminate(flag)
  106. int flag;
  107. {
  108.         reset_colors();
  109.         v_clsvwk(work_handle);
  110.         appl_exit();
  111.         exit(flag);
  112. }
  113.  
  114. /* dummy routine, for short delay */
  115. dumdum()
  116. {
  117.         int i;
  118.         for (i=0;i++<42-(round<<1););
  119. }
  120.  
  121. reset_game()
  122. {
  123.         missile=FALSE; /* kill missile */
  124.         clear_sky();
  125.         speed=2; /* maximum speed */
  126.         score=round=death_toll=0; ships=3;
  127.         update_scorebox();
  128.         cannon_x=0;
  129.         put (&cannon,cannon_x,cannon_y,fdb_XOR); /* cannon appears */
  130.         init_ufos();
  131. }
  132.  
  133. /* fill sky with stars */
  134. clear_sky()
  135. {
  136.         int star;
  137.         v_clrwk(work_handle);
  138.         vsl_color(work_handle,1);
  139.         vswr_mode(work_handle,1); /* replace */
  140.         for (star=0;star<100;star++)
  141.         {
  142.                 pxyarray[2]=pxyarray[0]=rnd(work_out[0]);
  143.                 pxyarray[3]=pxyarray[1]=rnd(work_out[1]);
  144.                 v_pline(work_handle,2,pxyarray);
  145.         }
  146. }
  147.  
  148. /* allow player to pause game by pressing a key */
  149. check_for_pause()
  150. {
  151.         int key,which;
  152.         /* poll keyboard by waiting for a null time duration */
  153.         which=evnt_multi(MU_TIMER|MU_KEYBD,0,0,0,0,0,0,0,0,0,0,0,0,0,&dummy,0,0,
  154.                 &dummy,&dummy,&dummy,&dummy,&key,&dummy);
  155.         if (which & MU_KEYBD) evnt_keybd();
  156. }
  157.  
  158. /* initializes positions and vectors for saucers */
  159. init_ufos()
  160. {
  161.         int sprite;
  162.         death_toll=0; /* no sprites dead yet */
  163.         for (sprite=0;sprite<NUMSPRITES;sprite++)
  164.         {
  165.                 isdead[sprite]=xacc[sprite]=yacc[sprite]=0;
  166.                 while (xacc[sprite]==0) xacc[sprite]=(speed>>1)-rnd(speed+1);
  167.                 while (yacc[sprite]==0) yacc[sprite]=(speed>>1)-rnd(speed+1);
  168.                 x[sprite]=8+rnd(xborder-8);
  169.                 y[sprite]=8+rnd(yborder-50);
  170.                 put (&saucer,x[sprite],y[sprite],fdb_XOR); /* make it appear */
  171.         }
  172. }
  173.  
  174. update_scorebox()
  175. {
  176.         char temp[20];
  177.         int y,d;
  178.         pxyarray[0]=0; pxyarray[1]=textline;
  179.         pxyarray[2]=work_out[0]; pxyarray[3]=work_out[1];
  180.         vswr_mode(work_handle,1); /* replace */
  181.         vsf_color(work_handle,1); /* white */
  182.         vsf_interior(work_handle,1); /* solid */
  183.         v_bar(work_handle,pxyarray);
  184.         vswr_mode(work_handle,2); /* transparent */
  185.         vsl_color(work_handle,COLORMODE? 3 : 0);
  186.         for (y=d=0;y<TEXTBOX;y+=d++)
  187.         {
  188.                 pxyarray[0]=0; pxyarray[1]=y+textline;
  189.                 pxyarray[2]=work_out[0]; pxyarray[3]=y+textline;
  190.                 v_pline(work_handle,2,pxyarray);
  191.         }
  192.         vsl_color(work_handle,1);
  193.         /* draw text in red, if possible */
  194.         vst_color(work_handle,COLORMODE? 2 : 0);
  195.         vst_alignment(work_handle,1,0,&dummy,&dummy); /* center */
  196.         v_gtext(work_handle,work_out[0]>>1,textline+(ch<<1)+(COLORMODE? 0 : ch),"ASTROPANIC");
  197.         vst_color(work_handle,0); /* draw text in black */
  198.         vst_alignment(work_handle,0,0,&dummy,&dummy); /* left */
  199.         sprintf(temp,"Cannons:%d  Level:%d",ships,round+1);
  200.         v_gtext(work_handle,cw,textline+ch*3,temp);
  201.         vst_alignment(work_handle,2,0,&dummy,&dummy); /* right */
  202.         sprintf(temp,"Score:%07lu0",score);
  203.         v_gtext(work_handle,work_out[0]-cw,textline+ch*3,temp);
  204.         vst_alignment(work_handle,0,0,&dummy,&dummy);
  205.         vst_color(work_handle,1);
  206. }
  207.  
  208. /* when cannon is hit, kill it */
  209. kill_cannon()
  210. {
  211.         int lum;
  212.         put (&cannon,cannon_x,cannon_y,fdb_XOR); /* remove cannon */
  213.         if (COLORMODE) setcolor(0,1000,0,0); /* flash screen */
  214.         else setcolor(0,1000,1000,1000); /* monochrome */
  215.         explode(cannon_x+(cannon.fd_w>>1),cannon_y+(cannon.fd_h>>1),8,1);
  216.         if (COLORMODE)
  217.                 for (lum=1000;lum>=0;setcolor(0,lum--,0,0));
  218.         else setcolor(0,0,0,0);
  219.         missile=FALSE; /* kill missile */
  220.         --ships; update_scorebox();
  221.         if (ships==0) { end_game(); return; }
  222.         SHOW_MOUSE;
  223.         if (ships==1)
  224.                 form_alert(1,"[3][|Last Cannon|][Ready!]");
  225.         else
  226.                 form_alert(1,"[3][|Next Cannon|][Ready!]");
  227.         HIDE_MOUSE;
  228.         clear_sky();
  229.         update_scorebox();
  230.         cannon_x=0;
  231.         put (&cannon,cannon_x,cannon_y,fdb_XOR); /* cannon appears */
  232.         init_ufos();
  233. }
  234.  
  235. /* explosion effect radiating from center */
  236. /* flag controls duration of sound effect */
  237.  
  238. explode(xcenter,ycenter,radius,flag)
  239. int xcenter,ycenter,radius,flag;
  240. {
  241.         static char boom[]=
  242.         {0,0, 1,0, 2,0, 3,0, 4,0, 5,0, 6,63, 7,0xf7, 8,0x10, 9,0,
  243.         10,0, 11,0, 12,10, 13,0, 255,0};
  244.         int r;
  245.         boom[25]=flag? 20 : 10;
  246.         Dosound(boom);
  247.         vswr_mode(work_handle,3); /* XOR */
  248.         vsf_interior(work_handle,0); /* hollow circle */
  249.         for (r=0;r<radius;v_circle(work_handle,xcenter,ycenter,r+=2));
  250.         for (r=0;r<radius;v_circle(work_handle,xcenter,ycenter,r+=2));
  251.         vswr_mode(work_handle,1); /* normal */
  252. }
  253.  
  254. end_game()
  255. {
  256.         SHOW_MOUSE;
  257.         if (form_alert(1,"[2][Play Again?][YES|NO]")==1)
  258.         {
  259.                 reset_game();
  260.                 HIDE_MOUSE;
  261.         }
  262.         else Terminate(0);
  263. }
  264.  
  265. /* moves cannon, checks for fire button */
  266. move_cannon()
  267. {
  268.         int button,x,y,oldx;
  269.         static int released=TRUE;
  270.         static char blip[]=
  271.         {0,0, 1,0, 2,10, 3,0, 4,0, 5,0, 6,0, 7,0xfd, 8,0, 9,16,
  272.         10,0, 11,0, 12,8, 13,4, 255,0};
  273.         oldx=cannon_x;
  274.         vq_mouse(work_handle,&button,&x,&y);
  275.         if (button&2)
  276.         {
  277.                 if (released)
  278.                 {
  279.                         if (missile) draw_missile(); /* erase old missile */
  280.                         Dosound(blip);
  281.                         missile=TRUE; missile_x=cannon_x+(cannon.fd_h>>1);
  282.                         missile_y=cannon_y;
  283.                         draw_missile();
  284.                         released=FALSE;
  285.                 }
  286.         }
  287.         else released=TRUE;
  288.         cannon_x=(x<work_out[0]-cannon.fd_w)? x : work_out[0]-cannon.fd_w;
  289.         if (cannon_x != oldx)
  290.         {
  291.                 put (&cannon,oldx,cannon_y,fdb_XOR);
  292.                 put (&cannon,cannon_x,cannon_y,fdb_XOR);
  293.         }
  294. }
  295.  
  296. /* moves missile to next position, if missile is on screen */
  297. update_missile()
  298. {
  299.         int sprite;
  300.         draw_missile(); /* erase old missile */
  301.         if ((missile_y-=MISSILE_SPEED)>TOPSCREEN)
  302.                 draw_missile(); /* draw new missile */
  303.         else missile=FALSE; /* end of mission */
  304.         for (sprite=0;sprite<NUMSPRITES;sprite++)
  305.         {
  306.                 if (!isdead[sprite] && missile_x>=x[sprite] && missile_x<=x[sprite]+saucer.fd_w)
  307.                         if ( (y[sprite]>=missile_y && y[sprite]<=missile_y+MISSILE_H) ||
  308.                                 (y[sprite]+saucer.fd_h>=missile_y && y[sprite]+saucer.fd_h<=missile_y+MISSILE_H) )
  309.                         {
  310.                                 killsprite(sprite);
  311.                                 break;
  312.                         }
  313.         }
  314. }
  315.  
  316. killsprite(which)
  317. int which;
  318. {
  319.         put (&saucer,x[which],y[which],fdb_XOR); /* remove saucer */
  320.         draw_missile(); /* remove missile */
  321.         missile=FALSE;
  322.         explode(x[which]+(saucer.fd_w>>1),y[which],8,0);
  323.         isdead[which]=TRUE;
  324.         score+=(COLORMODE? y[which] : (y[which]<<1));
  325.         update_scorebox();
  326.         if (++death_toll==NUMSPRITES)
  327.         {
  328.                 init_ufos();
  329.                 if (round<20)
  330.                 {
  331.                         round++; /* next round */
  332.                         update_scorebox();
  333.                 }
  334.                 if (speed<(COLORMODE? 16 : 24)) speed++;
  335.         }
  336. }
  337.  
  338. /* draws missile at missile_x, missile_y, with XOR */
  339. draw_missile()
  340. {
  341.         vswr_mode(work_handle,3); /* XOR drawing mode */
  342.         vsl_color(work_handle,1); /* white */
  343.         pxyarray[0]=missile_x; pxyarray[1]=missile_y-MISSILE_H;
  344.         pxyarray[2]=missile_x; pxyarray[3]=missile_y;
  345.         v_pline(work_handle,2,pxyarray);
  346.         vswr_mode(work_handle,1); /* replace mode */
  347.         vsl_color(work_handle,1); /* black */
  348. }
  349.  
  350. /* Saves colors in global array colortab[] */
  351. save_colors()
  352. {
  353.         int i;
  354.         for (i=0;i<16;i++)
  355.                 vq_color(work_handle,i,0,colortab[i]);
  356. }
  357.  
  358. /* sets colors for this program */
  359. set_colors()
  360. {
  361.         save_colors();
  362.         setcolor(0,0,0,0); /* black */
  363.         setcolor(1,1000,1000,1000); /* white */
  364. }
  365.  
  366. setcolor(index,red,green,blue)
  367. int index,red,green,blue;
  368. {
  369.         int rgb_in[3];
  370.         rgb_in[0]=red; rgb_in[1]=green; rgb_in[2]=blue;
  371.         vs_color(work_handle,index,rgb_in);
  372. }
  373.  
  374. reset_colors()
  375. {
  376.         int i;
  377.         for (i=0;i<16;i++)
  378.                 vs_color(work_handle,i,colortab[i]);
  379. }
  380.         
  381. /* waits for a period of time */
  382. delay(period)
  383. int period;
  384. {
  385.         evnt_timer(period,0);
  386. }
  387.  
  388. /* returns TRUE if mouse button clicked, else FALSE */
  389. int clicked()
  390. {
  391.         int pstatus;
  392.         vq_mouse(work_handle,&pstatus,&dummy,&dummy);
  393.         return(pstatus&2);
  394. }
  395.  
  396. /* initializes the shapes according to screen resolution */
  397. init_shapes()
  398. {
  399.         screen.fd_addr=0; /* screen memory */
  400.         switch (work_out[13]) /* number of colors */
  401.         {
  402.         /* high res, 640 x 400 */
  403.         case 2: ufo_high();
  404.                         cannon_high();
  405.                         break;
  406.         /* medium res, 640 x 200 */
  407.         case 4: ufo_med();
  408.                         cannon_med();
  409.                         break;
  410.         /* low res, 320 x 200 */
  411.         case 16: ufo_low();
  412.                          cannon_low();
  413.                          break;
  414.         }
  415. }
  416.  
  417. /* initializes data for high-res saucer shape */
  418. ufo_high()
  419. {
  420.         static int ufohigh[]=
  421.         {7,0x8000,0x18,0x6000,0x20,0x1000,0x40,0x800,0x1ff,0xfc00,
  422.         0x1e49,0x27c0,0x7fff,0xfff0,0x8000,8,0x6aaa,0xaab0,0x1d55,
  423.         0x55c0,0x3ff,0xfe00,0,0};
  424.         saucer.fd_addr=(char *) ufohigh; /* raster memory */
  425.         saucer.fd_w=29; /* width in pixels */
  426.         saucer.fd_h=11; /* height in rows */
  427.         saucer.fd_wdwidth=2; /* width in words */
  428.         saucer.fd_stand=1; /* standard FDB? */
  429.         saucer.fd_nplanes=1; /* one plane */
  430. }
  431.  
  432. cannon_high()
  433. {
  434.         static int cannonhigh[]=
  435.         {16,0,16,0,16,0,0x38,0,0x54,0,0x306c,0x19c0,0x68aa,0x2df0,
  436.         0x68aa,0x2c08,0xc4ba,0x46b0,0xd3ab,0x97c0,0xc8ba,0x2600,
  437.         0xd6aa,0xd600,0xd6aa,0xd600,0xc8ba,0x2600,0xd3ab,0x9600,
  438.         0xc4ba,0x4600,0x68aa,0x2c00,0x6828,0x2c00,0x307c,0x1800,0x38,0};        
  439.  
  440.         cannon.fd_addr=(char *) cannonhigh; /* raster memory */
  441.         cannon.fd_w=23; /* width in pixels */
  442.         cannon.fd_h=20; /* height in rows */
  443.         cannon.fd_wdwidth=2; /* width in words */
  444.         cannon.fd_stand=1; /* standard FDB? */
  445.         cannon.fd_nplanes=1; /* one plane */
  446. }
  447.  
  448. /* initializes data for medium-res saucer shape */
  449. ufo_med()
  450. {
  451.         static int ufomed[]=
  452.         {
  453.                 0,0,0xf800,0,0,0x701,
  454.                 15,8,0xff00,0x100,0,0x800,
  455.                 0x1ff,0x1ff,0xfff8,0xfff8,0x28,0x701,
  456.                 0xffff,0x5555,0xffff,0x5555,0xf1c0,0x5800,
  457.                 0x3fff,0x3fff,0xffff,0xffff,0x8000,0x8000,
  458.                 0,0xff,0,0xffe0,0x8b0,0
  459.         };
  460.         saucer.fd_addr=(char *) ufomed; /* raster memory */
  461.         saucer.fd_w=36; /* width in pixels */
  462.         saucer.fd_h=6; /* height in rows */
  463.         saucer.fd_wdwidth=3; /* width in words */
  464.         saucer.fd_stand=0; /* not a standard FDB */
  465.         saucer.fd_nplanes=2; /* two planes */
  466. }
  467.  
  468. cannon_med()
  469. {
  470.         static int cannonmed[]=
  471.         {       /* plane zero */
  472.                 0x40,0, 0x40,0, 0xa0,0, 0x1f0,0, 0x21f0,0x8000,
  473.                 0x51f1,0x4000, 0xd7fd,0x6000, 0xdfff,0x6000,
  474.                 0xd9f3,0x6000, 0x50a1,0x4000, 0x2000,0x8000,
  475.                 /* plane one */
  476.                 0,0, 0,0, 0xe0,0, 0x1b0,0, 0x21f0,0x8000,
  477.                 0x7111,0xc000, 0xf7fd,0xe000, 0xff1f,0xe000,
  478.                 0xf9f3,0xe000, 0x70e1,0xc000, 0x2000,0x8000
  479.         };      
  480.  
  481.         cannon.fd_addr=(char *) cannonmed; /* raster memory */
  482.         cannon.fd_w=19; /* width in pixels */
  483.         cannon.fd_h=11; /* height in rows */
  484.         cannon.fd_wdwidth=2; /* width in words */
  485.         cannon.fd_stand=1; /* standard FDB? */
  486.         cannon.fd_nplanes=2; /* two planes */
  487.         vr_trnfm(work_handle,&cannon,&cannon);
  488. }
  489.  
  490. /* initializes shapes for low resolution */
  491. ufo_low()
  492. {
  493.         static int ufolow[]=
  494.         {0,7,0,7,0,0x8000,0,0x8000,
  495.          1,0x1e,0,0x1e,0x8000,0x6000,0,0x6000,
  496.          0,0x3f,0,0x3f,0x4000,0xb000,0,0xb000,
  497.          0,0x7f,0,0x7f,0,0xf800,0,0xf800,
  498.          0x1ff,0,0,0,0xfc00,0,0,0,
  499.          0,1e49,0x1b6,0x1b6,0,0x27c0,0xd800,0xd800,
  500.          0,0x7fff,0x7fff,0x7fff,0,0xfff0,0xfff0,0xfff0,
  501.          0x8000,0,0xffff,0,8,0,0xfff8,0,
  502.          0x6aaa,0x1555,0x7fff,0,0xaab0,0x5540,0xfff0,0,
  503.          0x1d55,0x1d55,0x1d55,0x1d55,0x55c0,0x55c0,0x55c0,0x55c0,
  504.          0x3ff,0x3ff,0,0,0xfe00,0xfe00,0,0};
  505.  
  506.         saucer.fd_addr=(char *) ufolow; /* raster memory */
  507.         saucer.fd_w=29; /* width in pixels */
  508.         saucer.fd_h=11; /* height in rows */
  509.         saucer.fd_wdwidth=2; /* width in words */
  510.         saucer.fd_stand=0; /* not a standard FDB */
  511.         saucer.fd_nplanes=4; /* four planes */
  512. }
  513.  
  514. cannon_low()
  515. {
  516.         static int cannonlow[]=
  517.         {0,16,0,0,0,0,0,0,
  518.          0,16,0,0,0,0,0,0,
  519.          0,16,0,0,0,0,0,0,
  520.          0,0x38,0,0,0,0,0,0,
  521.          0x28,0x54,0,0,0,0,0,0,
  522.          0,0x307c,0x3010,0x3000,0x1c0,0x1800,0x1800,0x1800,
  523.          0x1000,0x78fe,0x7854,0x7800,0x11f0,0x3c00,0x3c00,0x3c00,
  524.          0x1000,0x78fe,0x7854,0x7800,0x1008,0x3c00,0x3c00,0x3c00,
  525.          0x3800,0xfcfe,0xfc44,0xfc00,0x38b0,0x7e00,0x7e00,0x7e00,
  526.          0x2c00,0xefff,0xff55,0xef01,0x69c0,0xee00,0xfe00,0xee00,
  527.          0x3701,0xf7ff,0xff45,0xf701,0xd800,0xde00,0xfe00,0xde00,
  528.          0x2901,0xe9ff,0xff55,0xe901,0x2800,0x2e00,0xfe00,0x2e00,
  529.          0x2901,0xe9ff,0xff55,0xe901,0x2800,0x2e00,0xfe00,0x2e00,
  530.          0x3701,0xf7ff,0xff45,0xf701,0xd800,0xde00,0xfe00,0xde00,
  531.          0x2c00,0xefff,0xff55,0xef01,0x6800,0xee00,0xfe00,0xee00,
  532.          0x3800,0xfcfe,0xfc44,0xfc00,0x3800,0x7e00,0x7e00,0x7e00,
  533.          0x1000,0x78fe,0x7854,0x7800,0x1000,0x3c00,0x3c00,0x3c00,
  534.          0x1000,0x787c,0x7854,0x7800,0x1000,0x3c00,0x3c00,0x3c00,
  535.          0,0x307c,0x3000,0x3000,0,0x1800,0x1800,0x1800,
  536.          0x38,0,0,0,0,0,0,0};   
  537.  
  538.         cannon.fd_addr=(char *) cannonlow; /* raster memory */
  539.         cannon.fd_w=23; /* width in pixels */
  540.         cannon.fd_h=20; /* height in rows */
  541.         cannon.fd_wdwidth=2; /* width in words */
  542.         cannon.fd_stand=0; /* not standard FDB */
  543.         cannon.fd_nplanes=4; /* four planes */
  544. }
  545.  
  546. put(shape,xpos,ypos,mode)
  547. struct my_fdb *shape;
  548. int xpos,ypos,mode;
  549. {
  550.         pxyarray[0]=0; pxyarray[1]=0;
  551.         pxyarray[2]=shape->fd_w-1; pxyarray[3]=shape->fd_h-1;
  552.         pxyarray[4]=xpos; pxyarray[5]=ypos;
  553.         pxyarray[6]=xpos+pxyarray[2];
  554.         pxyarray[7]=ypos+pxyarray[3];
  555.         vro_cpyfm(work_handle,mode,pxyarray,shape,&screen);
  556. }
  557.  
  558. init_workstation()
  559. {
  560.         int i, handle;
  561.         work_handle=handle=graf_handle(&cw,&ch,&dummy,&dummy);
  562.         for (i=0;i<10;work_in[i++]=1); work_in[10]=2;
  563.         v_opnvwk(work_in,&work_handle,work_out);
  564.         if (!work_handle) exit(-1); /* error if we can't open */
  565. }
  566.  
  567.