/* * CSE142, Spring 2000 * Homework 4 * Idyllic landscape animation STARTER PROGRAM * Modified by Rob Hanson * 5/10/2000 * name changed to I h8 BATZ * */ #include "gp142.h" #include #include #include #include /* * is included so the current time can be accessed * to initialize the random number generator. If you don't * use random numbers (and you don't have to) you can either * ignore this #include or delete it. */ /* Logical constants */ #define TRUE 1 #define FALSE 0 /*******************************************/ /* NEW CONSTANTS n stuff made by Robh */ /*******************************************/ #define MINE 14 /* Used for different weapons, (FUTURE VERSION) */ #define RELOAD 11 #define ATTACKA 12 #define ATTACKB 13 /* used by the rocket launcher (FUTURE VERSION) */ #define NUMBATS 4 #define MAXGUNSHOTS 20 #define AMMOCOUNT 8 /* number of bullets left */ #define LEVELCHANGE 1 #define SOUND 0 /* set to 1 for on */ /* set to 0 for off if you're in the IPL where beeping is BAD */ #define RELOADBEEP 4 /* number of beeps for reloading the gun */ #define BLOODSPLATSIZE 3 /* size of bloodsplat array */ #define MESSAGETIME 30 /* how long do we show a on screen message */ #define PRIMENUMBER 137 /* use a wierd prime number for the randomness of the lightening */ #define WINDOWWIDTH 4 /* for the castle NOT USED --FUTURE VERSION*/ #define NUMWINDOWS 4 /* for the castle NOT USED --FUTURE VERSION*/ #define BLOODSPLATSIZE 3 /* the size of the bloodplat array */ #define OFFSCREEN 500 /* off the screen,,,, duh */ #define NUMSTARS 4 /* u CAN change this, but stars don't have random placement, so nothing will happen */ #define SCOREMOD 10 /* 10 pts for each bat killed */ #define RELOADPENALTY 50 /* lose 50 pts for each relaod... teaches accuarcy = ) */ /* * For many of the GP142 functions, a line width of * zero means to fill the shape being drawn. The * constant FILL is used in function calls when a solid * shape is desired. */ #define FILL 0 /* * Symbolic constants. Change as needed. */ /* Menu buttons: */ /* Top-left coordinates of button palette */ #define MENU_TOP (GP142_YMAX - 5) #define MENU_LEFT (-GP142_XMAX + 5) /* Possible locations of mouse clicks: */ /* Mouse click in some button */ #define BUTTON_CLICK 1 /* Number of buttons */ #define NUM_BUTTONS 3 /* Height and width of buttons in pixels */ #define BUTTON_HEIGHT 25 #define BUTTON_WIDTH 100 /* Mouse click elsewhere */ #define OTHER_CLICK 0 /*mouse click on bat */ #define SHOTBAT 2 /* Coordinates of objects in the drawing */ /* y-coordinate of the top of the ground in the landscape */ #define HORIZON (- 2 * (GP142_YMAX / 8)) /* Other constants pertaining to objects in the scene */ #define MOON_RADIUS 20 #define MOON_FULLNESS 2.5 #define MAX_STAR_RADIUS 4 #define MAX_BAT_SIZE 10 #define MAX_BATS 10 /* 1 + max bats, its an array */ #define MAX_STARS 9 /* 1 + max stars, its an array */ /*********************************************************** *graphical constant coverup,,, this is asanine because we * *are using GRAPHICS, pixel values should be expected * *and by removing these constants from their functions * *the functions become more difficult to understand and * *modify * ***********************************************************/ #define LEVEL5 5 #define STAR1X 200 #define STAR1Y 90 #define STAR1R 3 #define STAR2X 150 #define STAR2Y 80 #define STAR2R 2 #define STAR3X 50 #define STAR3Y 30 #define STAR3R 3 #define STAR4X 130 #define STAR4Y 20 #define STAR2R 2 #define FLOWERX 3 #define FLOWERY 40 #define FLOWERR 2 #define PETALSIZE 8 #define BOATX 3 #define BOATXOFFSET 20 #define BOATY 25 #define BOATLEN 25 #define BOATMAST 40 #define MOONX 50 #define MOONY 35 #define BATSIZEOFFSET 3 #define BATYLINE 9 #define BATXLINE 3 #define BATLINEWIDTH 2 #define BAT2YLINE 7 #define BAT2XLINE 2 #define BAT2LINEWIDTH 1 #define TEXTOFFSET 15 #define TEXTSIZE 12 #define STARMOD 0.87 #define STARDIVIDE 2.0 #define MOUNTAINA 8 #define MOUNTAINB 5 #define MOUNTAINC 7 #define MOUNTAIND 3 #define MOUNTAINE 3 #define MOUNTAINF 8 #define MOUNTAING 4 #define MOUNTAINH 2 #define MOUNTAINI 5 #define MOUNTAINJ 5 #define MOUNTAINK 4 #define MOUNTAINL 3 #define MOUNTAINM 3 #define MOUNTAINN 4 #define MOUNTAINO 2 #define MOUNTAINP 7 #define MOUNTAINQ 3 #define MOUNTAINR 2 #define MOUNTAINS 3 #define LIGHTNINGSTART 150 #define LIGHTNINGW 2 #define LIGHTNINGX 70 #define LIGHTNINGY 70 #define LIGHTNING2X 10 #define LIGHTNING2Y 30 #define LIGHTNING3X 20 #define LIGHTNING3Y 0 #define LAKEXOFFSET 100 #define LAKESIZEMOD 3 #define LAKEYOFFSET 50 #define FLOWERA 15 #define FLOWERB 2 #define FLOWERC 10 #define FLOWERD 5 #define FLOWERE 3 #define FLOWERF 2 #define TREEXOFFSET 50 #define TREEYOFFSET 50 #define TREESIZEX 60 #define TREESIZEY 100 #define TREE2XOFFSET 55 #define TREE2YOFFSET 110 #define TREESIZER 30 #define BATGUTSXMOD 9 #define BATGUTSYMOD 7 #define BATGUTS2XMOD 8 #define BATGUTS2YMOD 3 #define BATGUTS3XMOD 5 #define BATGUTS3YMOD 9 #define SHELLX 20 #define SHELLY 8 #define SHELL2X 25 #define SHELL2Y 12 #define SHELL3Y 16 #define SHELL4X 19 #define SHELL4Y 10 #define SHELL5X 9 #define WEPX 3 #define WEPY 2 #define WEPS 6 #define BATERRORMARGIN 3 #define TEXTOFFSET2 10 #define FONTSIZE 12 #define BUTTONMOD 2 #define BUTTONFONTMOD 2 #define BOAT4 4 #define BOAT3 3 #define BOAT2 2 #define AMMOTXTPOS 14 #define LEVELXPOS 121 #define LEVELYPOS 120 #define LEVELXOFFSET 29 #define LEVELYOFFSET 30 #define LEVELTXTSIZE 10 #define WINXOFFSET 200 #define WINYOFFSET 2 #define WINTXTSIZE 30 #define LOSEXOFFSET 250 #define LOSEYOFFSET 2 #define MOONOFFSET 30 #define BATMOVEMOD 2 #define SOMETHINGISWRONGXOFFSET 16 #define CURRENTSCOREX 50 #define CURRENTSCOREY 49 #define HISCOREX 69 #define HISCOREY 70 /***************************************************************************** STRUCTS ! *****************************************************************************/ /* basic array structure for where stuff is */ typedef struct { int xpos; int ypos; int size; } locationsize; /* special array struct for stars */ typedef struct { int numstar; int xpos; int ypos; int radius; int color; } startype; /***************************************************************************** FUNCTION PROTOTYPES *****************************************************************************/ /* Weapon systems int x is a code for handling different systems*/ void weaponhandler(int switcher, int xpos, int ypos, locationsize gunshots[MAXGUNSHOTS], int* shots, int* ammo); /* Fires the gun at the butterflies... damn bats */ void firegun(int xpos, int ypos, locationsize gunshots[MAXGUNSHOTS], int* shots); /* we shot a BAT, draw its corpse */ int shotbat(int x, int y); /* Initialize random number generator. [Ignore or */ /* remove if your program doesn't use random numbers.] */ void initialize_random_numbers(); /* Initializes the moon parameters */ void init_moon(int *moon_x, int *moon_y); /* Draw a single boat */ void draw_boat(int boat_x, int boat_y, int boat_len, int boat_mast); /* Draw a single bat (buttefly) */ void draw_bat(locationsize bat[MAX_BATS], int i); /* draws the bulletfire */ void draw_weaponfire(int x, int y); /* Change flower field colors */ void change_colors(int *petal_color, int *flower_color); /* Draw the background, including the moon at coordinates moon_x and moon_y, the stars */ /* the tree, the flower(s), the boat, and the bat(s), return 1 if level change */ int main_graphics_engine(int moon_x, int moon_y, startype star[MAX_STARS], int flower_x, int flower_y, int flower_radius, int flower_color, int petal_radius, int petal_color, int boat_x, int boat_y, int boat_len, int boat_mast, locationsize bat[MAX_BATS], locationsize gunshots[MAXGUNSHOTS], int bloodsplat[BLOODSPLATSIZE], int ammo, int levelnum, int success, int counter, int loser, int score, int hiscore); /* Make stars blink */ void blink_star(startype star[MAX_STARS]); /* Move bat(s) */ void move_bat(locationsize bat[MAX_BATS], int levelnum); /* Update moon coordinates moon_x, moon_y for one tick */ void move_moon(int *moon_x, int *moon_y); /* Draw buttons */ void draw_buttons(void); /* returns the number of the bat that got BLASTED*/ int whichbat(int mouse_x, int mouse_y, locationsize bat[]); /* Return kind of mouse click (in a button, etc.) */ int classify_mouse_click(int mouse_x, int mouse_y, locationsize bat[]); /* Process button click at location x, y. React appropriately, depending on the requested event */ void handle_button(int x, int y, int *petal_color, int *flower_color, int *ammo, locationsize bat[MAX_BATS], int *levelnum, int*loser, int*success, int*score, int*num_bats_killed); /* Display error message if internal error is detected. */ void something_is_wrong (void); /* resets where the bats are */ void init_bats(locationsize bat[MAX_BATS], int levelnum); /* draws de castle */ void draw_castle(void); /***************************************************************************** MAIN *****************************************************************************/ /* * Main program contents: * - Major program variables that persist throughout execution * - Event loop that processes GP142 events until the user quits, * and updates variables and redraws the window as needed. */ int main(void) { /**************************************************************************/ /**** ADDED BY ROB HANSON 5/10/2000 for I h8 BATZ *************************/ /**************************************************************************/ int hiscore=0; /* do we really need a comment for this? */ int score=0; /* do we really need a comment for this? */ int loser=FALSE; /* we don't suck.... yet */ startype star[MAX_STARS]; /* startup the stars */ int bloodsplat[BLOODSPLATSIZE]={-OFFSCREEN,-OFFSCREEN}; /* no VISIBLE blood splats yet*/ int ammo=AMMOCOUNT; /* how much ammo ? */ locationsize bat[MAX_BATS]; /* get ready for bats */ locationsize gunshots[MAXGUNSHOTS]; /* keep track of where we've been shooting */ int levelnum=1; /* level number*/ int weaponfire; /* have shots been fired? flag */ int shot_bat_num; /* who did we shoot */ int i,j; /* i like counters */ int shots=0; /* we haven't fired yet */ int num_bats_killed=0; /* no bats dead */ int success=0; /* did we win? */ int counter=MESSAGETIME + 1; /* COUNTER!:*/ /** Counter default is 31, that way u have ** ** periodics from 0 to 30 for messages to ** ** be displayed on screen, the +1 MUST stay there **/ /* Event handling and buttons: */ int quit; /* = "user has selected quit" */ int event; /* the most recent GP142 event */ char key_pressed; /* last keyboard character from key event */ int mouse_x, mouse_y; /* x and y coordinates of latest mouse event*/ int click_kind; /* kind of mouse click (button, etc.) */ /* Information about the moon and stars: */ int moon_x, moon_y; /* screen x and y coordinates */ /* Information about the flowers */ int flower_x, flower_y; /* screen x and y coordinates */ int flower_radius, petal_radius; /* flower and petal radii */ int flower_color, petal_color; /* flower and petal colors */ /* Information about the boat */ int boat_x, boat_y; /* screen x and y coordinates */ int boat_len, boat_mast; /* length of the boat and height of the mast */ /* lets start the bats */ init_bats(bat, levelnum); /* Initialize random number generator */ initialize_random_numbers(); /* Initialize graphics package, clear the window, */ /* turn logging off, and start animation. */ GP142_open(); GP142_logging(LOG_OFF); GP142_clear(); GP142_animate(ANI_RUN); /* set initial location of the moon */ init_moon(&moon_x, &moon_y); /* set initial location of the stars */ star[0].xpos = GP142_XMAX - STAR1X; star[0].ypos = GP142_YMAX - STAR1Y; star[0].radius = STAR1R; star[0].color = WHITE; star[1].xpos = -GP142_XMAX + STAR2X; star[1].ypos = GP142_YMAX - STAR2Y; star[1].radius = STAR2R; star[1].color = YELLOW; star[0].numstar = NUMSTARS; star[2].xpos = GP142_XMAX - STAR3X; star[2].ypos = GP142_YMAX - STAR3Y; star[2].radius = STAR3R; star[2].color = WHITE; star[3].xpos = -GP142_XMAX + STAR4X; star[3].ypos = GP142_YMAX - STAR4Y; star[3].radius = STAR2R; star[3].color = YELLOW; /* set initial flower parameters */ flower_x = GP142_XMAX / FLOWERX; flower_y = -GP142_YMAX + FLOWERY; flower_radius = FLOWERR; flower_color = YELLOW; petal_radius = PETALSIZE; petal_color = RED; /* set initial conditions for the boat */ boat_x = GP142_XMAX / BOATX - BOATXOFFSET; boat_y = HORIZON - BOATY; boat_len = BOATLEN; boat_mast = BOATMAST; /* legacy variables from starter program */ /* Draw initial landscape, buttons, and traffic */ main_graphics_engine(moon_x,moon_y, star, flower_x, flower_y, flower_radius, flower_color, petal_radius, petal_color, boat_x, boat_y, boat_len, boat_mast, bat, gunshots, bloodsplat, ammo, levelnum, success, counter, loser, score, hiscore); draw_buttons(); /* * Main event loop: * ---- ----- ----- * Wait for the next user action, decode it, and call an * appropriate function to handle it. Repeat until the * user selects quit. */ quit = FALSE; while (!quit) { /* get next event */ event = GP142_await_event(&mouse_x, &mouse_y, &key_pressed); /* perform appropriate action depending on kind of event */ switch (event) { case GP142_QUIT: /* Quit selected */ quit = TRUE; break; case GP142_KBD: /* Key pressed. Not used now. If the program should */ /* react to keyboard events, insert something appropriate */ /* here. Note that scanf CANNOT be used with GP142. */ break; case GP142_MOUSE: /* Mouse click. Determine if in a menu button */ /* or elsewhere and process accordingly. */ click_kind = classify_mouse_click(mouse_x, mouse_y, bat); if (click_kind == BUTTON_CLICK) { handle_button(mouse_x, mouse_y, &petal_color, &flower_color, &ammo, bat, &levelnum, &loser, &success, &score, &num_bats_killed); } else if (click_kind == OTHER_CLICK) { /* they missed the bat or the menu */ /* can we shoot? */ if (ammo > 0) weaponfire=ATTACKA; /* we're shooting */ if (SOUND) /* is sound on or off? */ MessageBeep(-1); } else if (click_kind == SHOTBAT) { if(ammo > 0){ ammo--; shot_bat_num = whichbat(mouse_x, mouse_y, bat); bloodsplat[0] = mouse_x; /* KILL dat sucker */ bloodsplat[1] = mouse_y; bat[shot_bat_num].xpos= - OFFSCREEN; /* remove the flying bat from the screen */ bat[shot_bat_num].size= -1; /*make the shot bats have unique properties */ num_bats_killed++; score += num_bats_killed*SCOREMOD; if (levelnum >= LEVEL5) score += num_bats_killed*SCOREMOD; /* do better than level 5 and get twice the score */ if (SOUND) MessageBeep(-1); if(num_bats_killed == NUMBATS){ /* ALL dead bats ! */ success = TRUE; counter= 0; /* start timer before we go to level 2 */ } if (shot_bat_num == -1) something_is_wrong(); /*we shot a bat but couldn't figure out which bat*/ /* that ain't good */ } }else /* type of click unknown, but don't worry about it, we'll just keep going*/ break; case GP142_PERIODIC: /* Timer interval event. Update everything that needs the change */ /* as time advances. Animation should go here! */ switch(weaponfire){ case ATTACKA: weaponhandler(ATTACKA, mouse_x, mouse_y, gunshots, &shots, &ammo); weaponfire=0; /* we aren't shooting anymore */ break; case ATTACKB: //shoot rockets NOT USED in i h8 batz 1.0 case MINE: //DROP DA BOMB --NOT USED in i h8 batz 1.0 default: break; } /* has the lil bat escaped? */ for (i=0; i GP142_XMAX || bat[i].ypos < -GP142_YMAX || bat[i].ypos > GP142_YMAX ) && (bat[i].size != -1)){ /* NOT A SHOT BAT WHICH WE REMOVED */ loser=TRUE; if (score > hiscore) hiscore = score; /* NEW HIGH SCORE woohoo = P */ num_bats_killed = 0; /* kinda restart the game */ } /* u suck */ } counter++; move_moon(&moon_x, &moon_y); blink_star(star); blink_star(star); move_bat(bat,levelnum); break; default: /* unknown event don't worry about it*/ break; } /*end switch */ /* Redraw everything and check to see if we've changed levels, this was done in main_graphics_engine, cuz it knows everything*/ j=main_graphics_engine(moon_x, moon_y, star, flower_x, flower_y, flower_radius, flower_color, petal_radius, petal_color, boat_x, boat_y, boat_len, boat_mast, bat, gunshots, bloodsplat, ammo, levelnum, success, counter, loser, score, hiscore); draw_buttons(); if (j == LEVELCHANGE){ success= FALSE; counter=MESSAGETIME + 1; num_bats_killed = 0; levelnum++; init_bats(bat,levelnum); /*reinit the bats with the NEW level number */ } } /* end event loop */ /* Termination: shut down graphics window and exit */ GP142_close(); return 0; } /* end main */ /***************************************************************************** INITIALIZATION PROCEDURES *****************************************************************************/ /* Initializes the moon parameters */ void init_moon(int *moon_x, int *moon_y) { *moon_x = GP142_XMAX - MOONX; *moon_y = GP142_YMAX - MOONY; } /***************************************************************************** BACKGROUND LANDSCAPE *****************************************************************************/ /* Change flower field colors */ void change_colors(int *petal_color, int *flower_color) { *petal_color = (*petal_color + 1) % MAX_COLORS; *flower_color = (*flower_color + 1) % MAX_COLORS; } /* Draw a single bat of a given size at given screen x and y coordinates */ void draw_bat(locationsize bat[MAX_BATS], int i) { /* just for starters */ GP142_triangleXY(RED, bat[i].xpos, bat[i].ypos, bat[i].xpos - bat[i].size -BATSIZEOFFSET, bat[i].ypos + bat[i].size -BATSIZEOFFSET, bat[i].xpos - bat[i].size -BATSIZEOFFSET, bat[i].ypos - bat[i].size -BATSIZEOFFSET, FILL); GP142_triangleXY(RED, bat[i].xpos, bat[i].ypos, bat[i].xpos + bat[i].size -BATSIZEOFFSET, bat[i].ypos + bat[i].size -BATSIZEOFFSET, bat[i].xpos + bat[i].size -BATSIZEOFFSET, bat[i].ypos - bat[i].size -BATSIZEOFFSET, FILL); GP142_triangleXY(BLACK, bat[i].xpos, bat[i].ypos, bat[i].xpos - bat[i].size, bat[i].ypos + bat[i].size, bat[i].xpos - bat[i].size, bat[i].ypos - bat[i].size, FILL); GP142_triangleXY(BLACK, bat[i].xpos, bat[i].ypos, bat[i].xpos + bat[i].size, bat[i].ypos + bat[i].size, bat[i].xpos + bat[i].size, bat[i].ypos - bat[i].size, FILL); GP142_lineXY(YELLOW, bat[i].xpos, bat[i].ypos, bat[i].xpos - BATXLINE, bat[i].ypos + BATYLINE, BATLINEWIDTH); GP142_lineXY(YELLOW, bat[i].xpos, bat[i].ypos, bat[i].xpos + BATXLINE, bat[i].ypos + BATYLINE, BATLINEWIDTH); GP142_lineXY(BLACK, bat[i].xpos, bat[i].ypos, bat[i].xpos - BAT2XLINE, bat[i].ypos + BAT2YLINE, BAT2LINEWIDTH); GP142_lineXY(BLACK, bat[i].xpos, bat[i].ypos, bat[i].xpos + BAT2XLINE, bat[i].ypos + BAT2YLINE, BAT2LINEWIDTH); } /* Draw a boat at horizontal and vertical positions x and y and of the given length */ /* and mast height */ void draw_boat(int boat_x, int boat_y, int boat_len, int boat_mast) { GP142_rectangleXY(BLACK, boat_x - boat_len, boat_y, boat_x + boat_len, boat_y - BOAT4, FILL); GP142_triangleXY(RED, boat_x, boat_y, boat_x, boat_y + boat_mast, boat_x + boat_mast, boat_y + BOAT2 * boat_mast / BOAT3, FILL); } /* draw castle NOT USED IN THIS VERSION, THEREFORE CONSTANTS HAVE NOT BEEN SETUP*/ void draw_castle(void) { int i; GP142_rectangleXY(WHITE, -GP142_XMAX + 80, HORIZON + 20, -GP142_XMAX + 150, HORIZON + 60, FILL); GP142_rectangleXY(MED_GRAY, -GP142_XMAX + 80, HORIZON + 60, -GP142_XMAX + 90, HORIZON + 70, FILL); GP142_rectangleXY(BLACK, -GP142_XMAX + 82, HORIZON + 62, -GP142_XMAX + 88, HORIZON + 68, FILL); for (i=1; i<=NUMWINDOWS; i++){ GP142_rectangleXY(MED_GRAY, -GP142_XMAX + 90+ (WINDOWWIDTH *i), HORIZON + 40, -GP142_XMAX + 90+(WINDOWWIDTH * i), HORIZON + 50, FILL); GP142_rectangleXY(BLACK, -GP142_XMAX + 92+ (WINDOWWIDTH *i), HORIZON + 42, -GP142_XMAX + 92+(WINDOWWIDTH * i), HORIZON + 48, FILL); } GP142_rectangleXY(MED_GRAY, -GP142_XMAX + 150, HORIZON + 60, -GP142_XMAX + 140, HORIZON + 70, FILL); GP142_rectangleXY(BLACK, -GP142_XMAX + 148, HORIZON + 62, -GP142_XMAX + 142, HORIZON + 68, FILL); } /* Draw the background, including the moon at coordinates moon_x and moon_y and stars */ int main_graphics_engine(int moon_x, int moon_y, startype star[MAX_STARS], int flower_x, int flower_y, int flower_radius, int flower_color, int petal_radius, int petal_color, int boat_x, int boat_y, int boat_len, int boat_mast, locationsize bat[MAX_BATS], locationsize gunshots[MAXGUNSHOTS], int bloodsplat[BLOODSPLATSIZE], int ammo, int levelnum, int success, int counter, int loser, int score, int hiscore) { int text_offset = -GP142_XMAX + TEXTOFFSET; /* horizontal offset of text */ int text_size = TEXTSIZE; /* size of text font */ int i=0; /* Draw the sky */ GP142_rectangleXY(BLACK, -GP142_XMAX, -GP142_YMAX, GP142_XMAX, GP142_YMAX, FILL); /* Draw the moon */ GP142_circleXY(WHITE, moon_x, moon_y, MOON_RADIUS); GP142_ovalXY(BLACK, moon_x, moon_y - MOON_RADIUS, moon_x + (int)(MOON_FULLNESS * MOON_RADIUS), moon_y + MOON_RADIUS, FILL); /* Draw stars */ for(i=0; i MENU_LEFT) && (mouse_x < MENU_LEFT + BUTTON_WIDTH) && (mouse_y < MENU_TOP) && (mouse_y > (MENU_TOP - NUM_BUTTONS * BUTTON_HEIGHT))) return BUTTON_CLICK; else { for (i=0; i bat[i].xpos - BATERRORMARGIN) && (mouse_x < bat[i].xpos + bat[i].size) && (mouse_y < bat[i].ypos + bat[i].size) && (mouse_y > bat[i].ypos - BATERRORMARGIN)) return SHOTBAT; } return OTHER_CLICK; } } /* Classify mouse click at (mouse_x,mouse_y) and return kind */ int whichbat(int mouse_x, int mouse_y, locationsize bat[MAX_BATS]) { int i; for (i=0; i bat[i].xpos - BATERRORMARGIN) && (mouse_x < bat[i].xpos + bat[i].size) && (mouse_y < bat[i].ypos + bat[i].size) && (mouse_y > bat[i].ypos - BATERRORMARGIN)) return i; } return -1; /* ah crap! */ } /* Process button click at location x, y. React appropriately: */ /* i.e. change colors, tree tops, etc. if requested. */ void handle_button(int x, int y, int *petal_color, int *flower_color, int *ammo, locationsize bat[MAX_BATS], int *levelnum, int*loser, int*success, int *score, int *num_bats_killed) { int buttonNum; /* number of selected button */ /* Complain if x coordinate couldn't be inside a button */ if (x < MENU_LEFT || x > MENU_LEFT + BUTTON_WIDTH) { something_is_wrong(); return; } /* Convert y coordinate to button number from top. */ buttonNum = (MENU_TOP - y)/BUTTON_HEIGHT; switch(buttonNum) { case 0: /* change flower field colors */ change_colors(petal_color, flower_color); break; case 1: /* Reload the Guns */ weaponhandler(RELOAD,0,0,NULL,0,ammo); if (*score >= RELOADPENALTY) *score -= RELOADPENALTY; break; case 2: /* New Game */ *num_bats_killed =0; *levelnum =1; weaponhandler(RELOAD,0,0,NULL,0,ammo); init_bats(bat, *levelnum); *loser = FALSE; *score =0; /* hee hee */ *success = FALSE; break; default: /*Bad news if this is ever reached! */ GP142_animate(ANI_HALT); something_is_wrong(); break; } } /***************************************************************************** ANIMATED OBJECTS *****************************************************************************/ /* Make the stars blink */ void blink_star(startype star[MAX_STARS]) { int i; /* nifty trick... store the number of stars in the array, since therez no .sizeof() function */ for(i=0; i