home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Games / xrobots / graphics.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-03  |  13.6 KB  |  473 lines

  1. /*
  2.  * graphics.c  --  xrobots 
  3.  * 
  4.  * Copyright 1989 Brian Warkentine
  5.  * 
  6.  * Permission to use, copy, modify, distribute, and sell this software and its
  7.  * documentation for any purpose is hereby granted without fee, provided that
  8.  * the above copyright notice appear in all copies and that both that
  9.  * copyright notice and this permission notice appear in supporting
  10.  * documentation, and that the author's name not be used in advertising or
  11.  * publicity pertaining to distribution of the software without specific,
  12.  * written prior permission.  The author makes no representations about the
  13.  * suitability of this software for any purpose.  It is provided "as is"
  14.  * without express or implied warranty.
  15.  * 
  16.  * THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 
  17.  * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE 
  18.  * AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY 
  19.  * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 
  20.  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
  21.  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  22.  * 
  23.  * The author's current employer has no connection with this software, as it
  24.  * was written before being employed at Sun.  The following address is for 
  25.  * contacting the author only and does not imply any responsibility on the 
  26.  * behalf of Sun Microsystems.
  27.  * 
  28.  * Contact the author at:
  29.  *     Brian Warkentine  (brianw@Sun.COM)
  30.  *     Sun Microsystems
  31.  *     2550 Garcia Avenue
  32.  *     Mountain View, Ca 94043-1100
  33.  *
  34.  */
  35.  
  36. #include <X11/X.h>
  37. #include <X11/Intrinsic.h>
  38. #include <X11/Shell.h>
  39. #include "xrobots.h"
  40. #include "bitmaps.h"
  41. #include "icon.h"
  42.  
  43. static Pixmap playerP, dead_playerP, robotP, heapP, iconP;
  44. static Cursor upC, up_rightC, rightC, down_rightC, downC, 
  45.               down_leftC, leftC, up_leftC, stayC, cant_goC, thumbsC;
  46.  
  47. #define NUM_TMP_CURSOR_PIXMAPS 11
  48. static Pixmap tmp_pixmap[NUM_TMP_CURSOR_PIXMAPS]; 
  49.  
  50. /*----------------------------------------------------------------------*/
  51.  
  52. void
  53. init_pixmaps(top_shell)
  54.   Widget top_shell;
  55. {
  56. /*
  57.  * Let's make some pixmaps and some cursors.
  58.  * And then let's set the iconpixmap.
  59.  */
  60.   Pixmap tmpP;
  61.   XColor fgcolor,bgcolor;
  62.   Arg arg;
  63.  
  64.   playerP = XCreateBitmapFromData(display,playfield, 
  65.         Image_player_bits, Image_player_width, Image_player_height);
  66.  
  67.   dead_playerP = XCreateBitmapFromData(display,playfield, 
  68.         Image_player_dead_bits, Image_player_dead_width, 
  69.         Image_player_dead_height);
  70.  
  71.   iconP   = XCreateBitmapFromData(display,playfield,
  72.         icon_bits, icon_width, icon_height);
  73.  
  74.   robotP  = XCreateBitmapFromData(display,playfield, 
  75.         Image_robot_bits, Image_robot_width, Image_robot_height);
  76.  
  77.   heapP   = XCreateBitmapFromData(display,playfield, 
  78.         Image_heap_bits, Image_heap_width, Image_heap_height);
  79.  
  80. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  81.  
  82.   fgcolor.pixel = fg;
  83.   bgcolor.pixel = bg;
  84.   fgcolor.flags =  DoRed | DoGreen | DoBlue;
  85.   bgcolor.flags =  DoRed | DoGreen | DoBlue;
  86.   XQueryColor(display,DefaultColormapOfScreen(XtScreen(playfield_widget)), &fgcolor);
  87.   XQueryColor(display,DefaultColormapOfScreen(XtScreen(playfield_widget)), &bgcolor);
  88.  
  89.  
  90.   tmp_pixmap[0] = 
  91.   tmpP = XCreateBitmapFromData(display,playfield, up_bits, 
  92.                                   up_width, up_height);
  93.   upC  = XCreatePixmapCursor(display, tmpP, tmpP, &fgcolor,&bgcolor,8,8);
  94.  
  95.   tmp_pixmap[1] = 
  96.   tmpP = XCreateBitmapFromData(display,playfield, up_right_bits, 
  97.                                   up_right_width, up_right_height);
  98.   up_rightC = XCreatePixmapCursor(display, tmpP, tmpP, &fgcolor,&bgcolor,8,8);
  99.  
  100.   tmp_pixmap[2] = 
  101.   tmpP = XCreateBitmapFromData(display,playfield, right_bits, 
  102.                                   right_width, right_height);
  103.   rightC = XCreatePixmapCursor(display, tmpP, tmpP, &fgcolor,&bgcolor,8,8);
  104.  
  105.   tmp_pixmap[3] = 
  106.   tmpP = XCreateBitmapFromData(display,playfield, down_right_bits, 
  107.                                   down_right_width, down_right_height);
  108.   down_rightC = XCreatePixmapCursor(display, tmpP, tmpP, &fgcolor,&bgcolor,8,8);
  109.  
  110.   tmp_pixmap[4] = 
  111.   tmpP = XCreateBitmapFromData(display,playfield, down_bits, 
  112.                                   down_width, down_height);
  113.   downC = XCreatePixmapCursor(display, tmpP, tmpP, &fgcolor,&bgcolor,8,8);
  114.  
  115.   tmp_pixmap[5] = 
  116.   tmpP = XCreateBitmapFromData(display,playfield, down_left_bits, 
  117.                                   down_left_width, down_left_height);
  118.   down_leftC = XCreatePixmapCursor(display, tmpP, tmpP, &fgcolor,&bgcolor,8,8);
  119.  
  120.   tmp_pixmap[6] = 
  121.   tmpP = XCreateBitmapFromData(display,playfield, left_bits, 
  122.                                   left_width, left_height);
  123.   leftC = XCreatePixmapCursor(display, tmpP, tmpP, &fgcolor,&bgcolor,8,8);
  124.  
  125.   tmp_pixmap[7] = 
  126.   tmpP = XCreateBitmapFromData(display,playfield, up_left_bits, 
  127.                                   up_left_width, up_left_height);
  128.   up_leftC = XCreatePixmapCursor(display, tmpP, tmpP, &fgcolor,&bgcolor,8,8);
  129.  
  130.   tmp_pixmap[8] = 
  131.   tmpP = XCreateBitmapFromData(display,playfield, stay_bits, 
  132.                                   stay_width, stay_height);
  133.   stayC = XCreatePixmapCursor(display, tmpP, tmpP, &fgcolor,&bgcolor,8,8);
  134.  
  135.   tmp_pixmap[9] = 
  136.   tmpP = XCreateBitmapFromData(display,playfield, cant_go_bits, 
  137.                                   cant_go_width, cant_go_height);
  138.   cant_goC = XCreatePixmapCursor(display, tmpP, tmpP, &fgcolor,&bgcolor,8,8);
  139.  
  140.   tmp_pixmap[10] = 
  141.   tmpP = XCreateBitmapFromData(display,playfield, thumbs_down_bits, 
  142.                                   thumbs_down_width, thumbs_down_height);
  143.   thumbsC = XCreatePixmapCursor(display, tmpP, tmpP, &fgcolor,&bgcolor,
  144.                  thumbs_down_x_hot,thumbs_down_y_hot);
  145.  
  146.   XtSetArg(arg,XtNiconPixmap,iconP);
  147.   XtSetValues(top_shell,&arg,1);
  148. }
  149.  
  150. /*----------------------------------------------------------------------*/
  151.  
  152. static int cant_move;  /* set as a side effect of checking possible moves */
  153.  
  154. void
  155. auto_teleport()
  156. {
  157.   if(!cant_move)
  158.     return;
  159.   if(autoteleport && sonic_used) {
  160.     teleport();
  161.     return;
  162.   }
  163.   if(autoteleportalways)
  164.     teleport();
  165. }
  166.  
  167. static void
  168. display_ok_move(x,y)
  169.   int x,y;
  170. {
  171.  
  172.   if(can_go(x,y)) {
  173.     cant_move = 0;
  174.     if(!spiffy) return;
  175.             /* show the icon for a good move */
  176.     XDrawPoint(display, playfield, gc, 
  177.                pos_to_coord(x)+CELLSIZE/2,pos_to_coord(y)+CELLSIZE/2);
  178.   } else {
  179.     if(!spiffy) return;
  180.             /* or erase any previous dross */
  181.     if( INXRANGE(x) && INYRANGE(y) && (robot_array[x][y] == EMPTY))
  182.       XClearArea(display, playfield, 
  183.                  pos_to_coord(x), pos_to_coord(y),
  184.                  CELLSIZE, CELLSIZE, False);
  185.   }
  186. }
  187.  
  188. void
  189. display_possible_moves()
  190. {
  191.   cant_move = 1;
  192.  
  193.   display_ok_move( human_x-1,human_y-1 );
  194.   display_ok_move( human_x  ,human_y-1 );
  195.   display_ok_move( human_x+1,human_y-1 );
  196.   display_ok_move( human_x-1,human_y   );
  197.  
  198.   display_ok_move( human_x+1,human_y   );
  199.   display_ok_move( human_x-1,human_y+1 );
  200.   display_ok_move( human_x  ,human_y+1 );
  201.   display_ok_move( human_x+1,human_y+1 );
  202.  
  203. }
  204.  
  205.  
  206. void
  207. display_level()
  208. {
  209. /* Naive refresh algorithm.... */
  210.   int x,y;
  211.  
  212.   XClearWindow(display,playfield);
  213.   if(game_active)
  214.     XCopyPlane(display,playerP,playfield,gc,0,0,
  215.      Image_player_width,Image_player_height,
  216.      pos_to_coord(human_x),pos_to_coord(human_y),1);
  217.   else
  218.     XCopyPlane(display,dead_playerP,playfield,gc,0,0,
  219.      Image_player_dead_width,Image_player_dead_height,
  220.      pos_to_coord(human_x),pos_to_coord(human_y),1);
  221.  
  222.   for(y=0;y<MAXY;y++)
  223.   {
  224.     for(x=0;x<MAXX;x++)
  225.         switch (robot_array[x][y])
  226.         {
  227.           case ROBOT:
  228.             XCopyPlane(display,robotP,playfield,gc,0,0,
  229.                        Image_robot_width,Image_robot_height,
  230.                        pos_to_coord(x),pos_to_coord(y),1);
  231.             break;
  232.  
  233.           case HEAP:  
  234.             XCopyPlane(display,heapP,playfield,gc,0,0,
  235.                        Image_heap_width,Image_heap_height,
  236.                        pos_to_coord(x),pos_to_coord(y),1);
  237.             break;
  238.     }
  239.   }
  240. }
  241.  
  242.  
  243. void
  244. show_movement()
  245. {
  246. /* 
  247.  * draw just the changes.
  248.  */
  249.   int x,y;
  250.  
  251.   /* force a redraw of the area surrounding last position */
  252.   for(x=last_human_x-1;x<last_human_x+2;x++)
  253.     for(y=last_human_y-1;y<last_human_y+2;y++)
  254.       if( INXRANGE(x) && INYRANGE(y) )
  255.         robot_array_bak[x][y] = REDRAW;  
  256.  
  257.   /* 
  258.    * This is a little hacked up because the player isn't really in the 
  259.    * robot array.  Assigning the backup array to EMPTY avoids
  260.    * drawing over the player.
  261.    */
  262.   robot_array_bak[human_x][human_y] = EMPTY;   
  263.  
  264.   XCopyPlane(display,playerP,playfield,gc,0,0,
  265.         Image_player_width,Image_player_height,
  266.         pos_to_coord(human_x),pos_to_coord(human_y),1);
  267.  
  268.   for(y=0;y<MAXY;y++)
  269.   {
  270.     for(x=0;x<MAXX;x++)
  271.       if(robot_array[x][y] != robot_array_bak[x][y])
  272.         switch (robot_array[x][y])
  273.         {
  274.           case ROBOT:
  275.             XCopyPlane(display,robotP,playfield,gc,0,0,
  276.                        Image_robot_width,Image_robot_height,
  277.                        pos_to_coord(x),pos_to_coord(y),1);
  278.             break;
  279.  
  280.           case HEAP:
  281.             XCopyPlane(display,heapP,playfield,gc,0,0,
  282.                        Image_heap_width,Image_heap_height,
  283.                        pos_to_coord(x),pos_to_coord(y),1);
  284.             break;
  285.           default:
  286.             XClearArea(display, playfield, 
  287.                        pos_to_coord(x), pos_to_coord(y),
  288.                        CELLSIZE, CELLSIZE, False);
  289.     }
  290.   }
  291. }
  292.  
  293.  
  294.  
  295. /*ARGSUSED*/
  296. XtEventHandler
  297. redisplay_level(w, closure, event)
  298.   Widget w;
  299.   caddr_t closure;
  300.   XExposeEvent *event;
  301. {
  302. /* refresh entire screen -- e.g. expose events.  Just a little naive. */
  303.   display_level();
  304.   display_possible_moves();
  305.   XFlush(display);
  306. }
  307.  
  308.  
  309. void
  310. update_pointer(direction)
  311.   int direction;
  312. {
  313. /*
  314.  * set the cursor to the appropriate one.
  315.  */
  316.   int tmp_human_x = human_x, tmp_human_y = human_y;
  317.  
  318.   if(direction & UP)    tmp_human_y--;
  319.   if(direction & DOWN)  tmp_human_y++;
  320.   if(direction & LEFT)  tmp_human_x--;
  321.   if(direction & RIGHT) tmp_human_x++;
  322.  
  323.   if(!can_go(tmp_human_x,tmp_human_y)) {
  324.     XDefineCursor(display,playfield,cant_goC);
  325.     return;
  326.     }
  327.   if(direction&LEFT)
  328.     if(direction&UP)
  329.       XDefineCursor(display,playfield,up_leftC);
  330.     else 
  331.       if(direction&DOWN)
  332.           XDefineCursor(display,playfield,down_leftC);
  333.       else
  334.         XDefineCursor(display,playfield,leftC);
  335.  
  336.    if(direction&RIGHT)
  337.     if(direction&UP)
  338.       XDefineCursor(display,playfield,up_rightC);
  339.     else 
  340.       if(direction&DOWN)
  341.           XDefineCursor(display,playfield,down_rightC);
  342.       else
  343.         XDefineCursor(display,playfield,rightC);
  344.  
  345.   if(direction == UP)
  346.         XDefineCursor(display,playfield,upC);
  347.   if(direction == DOWN)
  348.         XDefineCursor(display,playfield,downC);
  349.   if(direction == STILL)
  350.         XDefineCursor(display,playfield,stayC);
  351.     
  352.  
  353. }
  354.  
  355.  
  356. /*----------------------------------------------------------------------*/
  357.  
  358. void free_pixmaps()
  359. {
  360.   int i;
  361.  
  362.   XFreeCursor(display,upC);
  363.   XFreeCursor(display,up_rightC);
  364.   XFreeCursor(display,rightC);
  365.   XFreeCursor(display,down_rightC);
  366.   XFreeCursor(display,downC);
  367.   XFreeCursor(display,down_leftC);
  368.   XFreeCursor(display,leftC); 
  369.   XFreeCursor(display,up_leftC); 
  370.   XFreeCursor(display,stayC);
  371.   XFreeCursor(display,thumbsC);
  372.   XFreeCursor(display,cant_goC);
  373.   for(i=0;i++;i<NUM_TMP_CURSOR_PIXMAPS) 
  374.     XFreePixmap(display,tmp_pixmap[i]);
  375.  
  376.   XFreePixmap(display,playerP);
  377.   XFreePixmap(display,dead_playerP);
  378.   XFreePixmap(display,robotP);
  379.   XFreePixmap(display,iconP);
  380.   XFreePixmap(display,heapP);
  381.  
  382. }
  383.  
  384.  
  385.  
  386. /*----------------------------------------------------------------------*/
  387.  
  388. void
  389. do_death()
  390. {
  391.   XDefineCursor(display,playfield,thumbsC);
  392.   XCopyPlane(display,dead_playerP,playfield,gc,0,0,
  393.      Image_player_dead_width,Image_player_dead_height,
  394.      pos_to_coord(human_x),pos_to_coord(human_y),1);
  395.   XFlush(display);
  396. }
  397.  
  398. /*----------------------------------------------------------------------*/
  399.  
  400. void
  401. show_teleport()
  402. {
  403. /* 
  404.  * Cheap animation... but it needs a fast server
  405.  */
  406. unsigned int i;
  407.  
  408.   if(!spiffy) return;
  409.  
  410.   for(i=100;i>0;i-=10) {
  411.     XDrawArc(display,playfield,gc,
  412.       pos_to_coord(human_x)+(CELLSIZE/2)-(i/2)-2,
  413.       pos_to_coord(human_y)+(CELLSIZE/2)-(i/2)-2,
  414.       i,i,0,64*360);
  415.     XFlush(display);
  416.   }
  417. }
  418.  
  419. /*----------------------------------------------------------------------*/
  420.  
  421. static void
  422. do_sonic(agc)
  423. GC agc;
  424. {
  425. /* 
  426.  * do some effects for the sonic screwdriver...
  427.  */
  428. #define SPACING 3
  429. int center_x = pos_to_coord(human_x)+(CELLSIZE/2)-2,
  430.     center_y = pos_to_coord(human_y)+(CELLSIZE/2)-2;
  431. int i;
  432.  
  433.   if(!spiffy) return;
  434.  
  435.   for(i=pos_to_coord(human_x-1);i<pos_to_coord(human_x+2);i+=SPACING) {
  436.     XDrawLine(display,playfield,agc,center_x,center_y,i,pos_to_coord(human_y-1));
  437.     XCopyPlane(display,playerP,playfield,gc,0,0,
  438.      Image_player_width,Image_player_height,
  439.      pos_to_coord(human_x),pos_to_coord(human_y),1);
  440.   }
  441.  
  442.   for(i=pos_to_coord(human_y-1);i<pos_to_coord(human_y+2);i+=SPACING) {
  443.     XDrawLine(display,playfield,agc,center_x,center_y,pos_to_coord(human_x+2),i);
  444.     XCopyPlane(display,playerP,playfield,gc,0,0,
  445.      Image_player_width,Image_player_height,
  446.      pos_to_coord(human_x),pos_to_coord(human_y),1);
  447.   }
  448.  
  449.   for(i=pos_to_coord(human_x+2);i>pos_to_coord(human_x-1);i-=SPACING) {
  450.     XDrawLine(display,playfield,agc,center_x,center_y,i,pos_to_coord(human_y+2));
  451.     XCopyPlane(display,playerP,playfield,gc,0,0,
  452.      Image_player_width,Image_player_height,
  453.      pos_to_coord(human_x),pos_to_coord(human_y),1);
  454.   }
  455.  
  456.   for(i=pos_to_coord(human_y+2);i>pos_to_coord(human_y-1);i-=SPACING) {
  457.     XDrawLine(display,playfield,agc,center_x,center_y,pos_to_coord(human_x-1),i);
  458.     XCopyPlane(display,playerP,playfield,gc,0,0,
  459.      Image_player_width,Image_player_height,
  460.      pos_to_coord(human_x),pos_to_coord(human_y),1);
  461.   }
  462.   XFlush(display);
  463. }
  464.  
  465.  
  466. void
  467. show_sonic()
  468. {
  469.   do_sonic(gc);        /* do it, */
  470.   do_sonic(cleargc);    /* then erase it. */
  471. }
  472.  
  473.