home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Games / xinvaders / base.c next >
Encoding:
C/C++ Source or Header  |  1995-05-03  |  6.9 KB  |  349 lines

  1. /* 
  2. Copyright notice:
  3.  
  4. This is mine.  I'm only letting you use it.  Period.  Feel free to rip off
  5. any of the code you see fit, but have the courtesy to give me credit.
  6. Otherwise great hairy beasties will rip your eyes out and eat your flesh
  7. when you least expect it.
  8.  
  9. Jonny Goldman <jonathan@think.com>
  10.  
  11. Wed May  8 1991
  12. */
  13.  
  14. /* base.c - handle movement, etc. of the base. */
  15.  
  16. #include "vaders.h"
  17.  
  18. extern int paused;
  19. Boolean basedestroyed;
  20.  
  21. static Boolean showingexplosion = FALSE;
  22.  
  23. void DrawBuildings();
  24.  
  25. #define BASEY (gameheight-base->height)
  26.  
  27. typedef struct _BaseRec {
  28.   int x;            /* Location. */
  29.   int v;            /* velocity */
  30.   int width, height;        /* box of this base. */
  31.   XImage *shape_image;        /* an XImage for the spaceship */
  32. } BaseRec, *Base;
  33.  
  34. BaseRec baserec;
  35.  
  36. Base base = &baserec;
  37.  
  38. XImage *explosion;
  39.  
  40. #define BaseNearPoint(base, x, y)    \
  41.   ((base)->x <= (x) && (x) < (base)->x + (base)->width  && \
  42.    y <= BASEY + (base)->height && y > BASEY)
  43.  
  44. #include "base1.bit"
  45. #include "base2.bit"
  46. #include "explode1.bit"
  47. #include "explode2.bit"
  48.  
  49. int ReadBaseImage()
  50. {
  51.   unsigned int width, height;
  52.   int x_hot, y_hot;
  53.   char *data, filename[255];
  54.   int status;
  55.  
  56.   base->width = (scale == 1) ? base1_width : base2_width;
  57.   base->height = (scale == 1) ? base1_height : base2_height;
  58.  
  59.   base->shape_image = XCreateImage(dpy,
  60.                    DefaultVisual(dpy, DefaultScreen(dpy)),
  61.                    1,
  62.                    XYBitmap,
  63.                    0,
  64.                    (scale == 1) ? base1_bits : base2_bits,
  65.                    base->width, base->height,
  66.                    8, 0);
  67.  
  68.   base->shape_image->bitmap_bit_order = LSBFirst;
  69.   base->shape_image->byte_order = LSBFirst;
  70.  
  71.   explosion = XCreateImage(dpy,
  72.                DefaultVisual(dpy, DefaultScreen(dpy)),
  73.                1,
  74.                XYBitmap,
  75.                0,
  76.                (scale == 1) ? explode1_bits : explode2_bits,
  77.                (scale == 1) ? explode1_width : explode2_width,
  78.                (scale == 1) ? explode1_height : explode2_height,
  79.                8, 0);
  80.   explosion->bitmap_bit_order = LSBFirst;
  81.   explosion->byte_order = LSBFirst;
  82.   
  83.   return BitmapSuccess;
  84. }
  85.  
  86. void InitBase()
  87. {
  88.     if( ReadBaseImage() != BitmapSuccess) {
  89.       fprintf(stderr, "Error reading base image.\n");
  90.       exit(20);
  91.     }
  92.     basedestroyed = TRUE;
  93.     showingexplosion = FALSE;
  94.     basetimerid = NULL;
  95.     base->v = 0;
  96. }
  97.  
  98.  
  99.  
  100. void PaintBase(gc)
  101. GC gc;
  102. {
  103.   XPutImage(dpy, gamewindow, gc, base->shape_image,
  104.         0, 0, base->x, gameheight-base->height, base->width, base->height);
  105. }
  106.  
  107.  
  108. ShowBase(i, gc)
  109. int i;
  110. GC gc;
  111. {
  112.   XPutImage(dpy, labelwindow, gc, base->shape_image,
  113.         0, 0, i*(base->width+2), gameheight/2-(3*base->height),
  114.         base->width, base->height);
  115. }
  116.  
  117. PaintBasesLeft()
  118. {
  119.   int i;
  120.   XDrawString(dpy, labelwindow, scoregc,
  121.           0, gameheight-(4*base->height),
  122.           "Bases", 5);
  123.   for(i = 0; i < basesleft; i++) {
  124.     ShowBase(i, basegc);
  125.   }
  126. }
  127.  
  128.  
  129. void ShowExplosion(gc)
  130. GC gc;
  131. {
  132.   XPutImage(dpy, gamewindow, gc, explosion,
  133.           0, 0, base->x, gameheight-base->height, explosion->width, explosion->height);
  134. }
  135.  
  136. void DestroyBase()
  137. {
  138.   if(!paused) {
  139.     PaintBase(backgc);
  140.     basedestroyed = TRUE;
  141.     showingexplosion = TRUE;
  142.     ShowExplosion(basegc);
  143.     if (basetimerid) XtRemoveTimeOut(basetimerid);
  144.     basetimerid = XtAddTimeOut(1000, MoveBase, (Opaque) MoveBase);
  145.   }
  146. }
  147.  
  148.  
  149. Boolean ShotHitsBase(x,y)
  150. int x,y;
  151. {
  152.   if(!basedestroyed && BaseNearPoint(base, x, y)) {
  153.     DestroyBase();
  154.     return TRUE;
  155.   }
  156.   return FALSE;
  157. }
  158.  
  159. ResetGame()
  160. {
  161.   static Arg args[1];
  162.  
  163.   spacer_shown = 0;
  164.   SuspendTimers();
  165.   XClearWindow(dpy, gamewindow);
  166.   paused = 1;
  167.   InitScore();
  168.   basesleft--;
  169.   level = 1;
  170.   CreateVaders(level);
  171.   spacer_counter = 1000;
  172.   numshots = 0;
  173.   numvshots = 0;
  174.   PaintAllVaders();
  175.   PaintBasesLeft();
  176.   InitBuildings();
  177.   DrawBuildings();
  178.   lastscore = 0;
  179.   PaintScore();
  180.   XSync(dpy, 0);
  181.   basedestroyed = FALSE;
  182.   base->x = base->v = 0;
  183.   showingexplosion = FALSE;
  184.   PaintBase(basegc);
  185.   XtSetArg(args[0], XtNlabel, "Start");
  186.   XtSetValues(pausebutton, args, 1);
  187. }
  188.  
  189. /*ARGSUSED*/
  190. void MoveBase(closure, id)
  191. Opaque closure;
  192. XtIntervalId id;
  193. {
  194.   if (closure != (Opaque) MoveBase) return;
  195.   if(!paused) {
  196.     if (basedestroyed) {
  197.       if (showingexplosion) {
  198.     ShowExplosion(backgc);
  199.     showingexplosion = FALSE;
  200.     basetimerid = XtAddTimeOut(2000, MoveBase, (Opaque) MoveBase);
  201.     return;
  202.       }
  203.       if (basesleft <= 0) {
  204.     ResetGame();
  205.     return;
  206.       }
  207.       base->x = 0;
  208.       basesleft--;
  209.       ShowBase(basesleft, backgc);
  210.       PaintBase(basegc);
  211.       PaintScore();
  212.       basedestroyed = FALSE;
  213.       base->v = 0;
  214.     }
  215.  
  216.     if (!paused)
  217.       basetimerid = XtAddTimeOut(basewait, MoveBase, (Opaque) MoveBase);
  218.     if(base->v) {
  219.       PaintBase(backgc);
  220.       base->x += base->v;
  221.       base->x = (base->x < 0) ? 0 :
  222.       ((base->x > gamewidth-base->width) ? gamewidth-base->width : base->x);
  223.       PaintBase(basegc);
  224.     }
  225.   }
  226. }
  227.  
  228. void MoveLeft()
  229. {
  230.   if(!paused) base->v= -scale;
  231. }
  232.  
  233.  
  234. void MoveRight()
  235. {
  236.   if(!paused) base->v = scale;
  237. }
  238.  
  239.  
  240. void Stop()
  241. {
  242.   if(!paused)
  243.     base->v = 0;
  244. }
  245.  
  246.  
  247. void Fire()
  248. {
  249.     if (!basedestroyed&&!paused) AddShot(base->x+base->width/2, gameheight-base->height);
  250. }
  251.  
  252. /* this part is for the buildings */
  253.  
  254. #define NUMBUILDINGS 4
  255. #define HUNKROWS 4
  256. #define NUMHUNKS 10
  257. #define HUNKWIDTH (2*scale)
  258. #define HUNKHEIGHT (4*scale)
  259. #define buildingwidth HUNKWIDTH*NUMHUNKS
  260. #define buildingheight HUNKHEIGHT*HUNKROWS
  261.  
  262. typedef struct {
  263.   int x,y;
  264.   Boolean hunks[HUNKROWS][NUMHUNKS];
  265. } BuildingRec, *Building;
  266.  
  267. BuildingRec buildings[NUMBUILDINGS];
  268.  
  269.  
  270. void DrawBuildingHunk(building, r, c, gc)
  271. Building building;
  272. int r,c;
  273. GC gc;
  274. {
  275.   int x, y;
  276.  
  277.   x = building->x+c*HUNKWIDTH;
  278.   y = gameheight-scale*45+r*HUNKHEIGHT;
  279.  
  280.   XFillRectangle(dpy, gamewindow, gc, x, y, HUNKWIDTH, HUNKHEIGHT);
  281. }
  282.  
  283. void ToastHunk(building,r,c)
  284. Building building;
  285. int r,c;
  286. {
  287.   building->hunks[r][c] = FALSE;
  288.   DrawBuildingHunk(building, r, c, backgc);
  289. }
  290.  
  291. Boolean ShotHitsBuilding(x, y)
  292. int x,y;
  293. {
  294.   int i, r, c;
  295.   Building building;
  296.  
  297.   for(i=0; i< NUMBUILDINGS; i++) {
  298.     building = &buildings[i];
  299.     if(x>=building->x && x<building->x+buildingwidth &&
  300.        y>=gameheight-scale*45 && y<gameheight-scale*45+buildingheight) {
  301.       r = (y-(gameheight-scale*45))/HUNKHEIGHT;
  302.       c = (x-building->x)/HUNKWIDTH;
  303.       if (r<0 || r>=HUNKROWS)
  304.     printf("Error in row");
  305.       if (c<0 || c>=NUMHUNKS)
  306.     printf("Error in column");
  307.       if(building->hunks[r][c]) {
  308.     ToastHunk(building, r,c);
  309.     return TRUE;
  310.       }
  311.       return FALSE;
  312.     }
  313.   }
  314.   return FALSE;
  315. }
  316.  
  317. InitBuildings()
  318. {
  319.   int i, j, k;
  320.  
  321.   for(i=0; i< NUMBUILDINGS; i++) {
  322.     buildings[i].x = i*((gamewidth ?
  323.              (scale*(VWIDTH-70)) :
  324.              (gamewidth-scale*70)))/4+scale*35+(HUNKWIDTH*NUMHUNKS)/2;
  325.     for (j=0; j<HUNKROWS; j++)
  326.       for (k = 0; k < NUMHUNKS; k++) 
  327.     buildings[i].hunks[j][k] = TRUE;
  328.   }
  329.   j--;
  330.  
  331.   for(i=0; i< NUMBUILDINGS; i++) {
  332.     buildings[i].hunks[0][0] = FALSE;
  333.     buildings[i].hunks[0][NUMHUNKS-1] = FALSE;
  334.     for (k = 3; k < NUMHUNKS-3; k++) 
  335.     buildings[i].hunks[j][k] = FALSE;
  336.   }
  337. }
  338.  
  339. void DrawBuildings()
  340. {
  341.   int i, j, k;
  342.  
  343.   for(i=0; i< NUMBUILDINGS; i++) {
  344.     for (j=0; j<HUNKROWS; j++)
  345.       for (k = 0; k < NUMHUNKS; k++) 
  346.     if(buildings[i].hunks[j][k]) DrawBuildingHunk(&buildings[i], j, k, buildinggc);
  347.   }
  348. }
  349.