/* $Id: game.c,v 1.97 2004/09/30 21:01:10 stpohle Exp $ game.c - procedures for the game. */ #include #include #include "bomberclone.h" #include "gfx.h" #include "network.h" #include "packets.h" #include "chat.h" #include "flyingitems.h" #include "menu.h" #include "keyb.h" #include "single.h" extern int blitdb_nr, blitrects_nr; Uint32 game_timediff, game_timediff1; static float hurrywarn_to; static int hurrywarn_state; static _menu *menu; void game_draw_info () { int i, x, j, col; char text[255]; char scrtext[255]; SDL_Rect src, dest; if (GT_MP && (chat.oldscreen == NULL || chat.window.x != 4 || chat.window.y != 4.5*16)) { chat_show (4, 4.5*16, gfx.res.x - 8, gfx.offset.y - 4.5*16); chat_setactive (0, 0); } if (bman.updatestatusbar) { redraw_logo (0, 0, gfx.res.x, (4.5 * 16)); dest.x = dest.y = 0; dest.h = 4.5 *16; dest.w = gfx.res.x; gfx_blitupdaterectadd (&dest); /* In Multiplayer mode draw Player names and count the players who are still alife. */ for (x = 0, j = 0, i = 0; i < MAX_PLAYERS; i++) if ((players[i].state & PSFM_used) != 0) { if (players[i].gfx_nr != -1 && PS_IS_used (players[i].state)) { src.x = 0; src.y = 0; src.w = dest.w = players[i].gfx->small_image->w; src.h = dest.h = players[i].gfx->small_image->h; dest.x = x; dest.y = j - 4; SDL_BlitSurface (players[i].gfx->small_image, &src, gfx.screen, &dest); } sprintf (scrtext, "%10s:%2d", players[i].name, players[i].points); if (!PS_IS_alife (players[i].state)) { // Player is dead if ((players[i].state & PSF_used) != PSF_used) col = 4; else col = 3; } else { // player is alife col = 0; } font_draw (x, j, scrtext, 0, col); x = x + 170; if (x >= gfx.res.x - (120 + 170)) { x = 0; j = j + 1.5 * font[0].size.x; } } x = gfx.res.x - 120; sprintf (text, "Bombs: %2d", players[bman.p_nr].bombs_n); font_draw (x, 0, text, 0, 0); sprintf (text, "Range: %2d", players[bman.p_nr].range); font_draw (x, 16, text, 0, 0); sprintf (text, "Speed: %1.1f", players[bman.p_nr].speed*10); font_draw (x, 32, text, 0, 0); if (players[bman.p_nr].special.type != 0) { col = players[bman.p_nr].special.type + FT_sp_trigger - 1; dest.x = x - 32; dest.y = 16; dest.w = gfx.menu_field[col]->w; dest.h = gfx.menu_field[col]->h; SDL_BlitSurface (gfx.menu_field[col], NULL, gfx.screen, &dest); } if (bman.state == GS_ready && GT_MP_PTPM) font_gfxdraw (100, 32, "Press F4 to start the game", 0, COLOR_yellow, 0xFFFF); else if (bman.state == GS_ready) font_gfxdraw (100, 32, "Waiting for the Server to Start", 0, COLOR_yellow, 0xFFFF); } /* draw the warning part */ if (map.state != MS_normal) { hurrywarn_to -= timediff; if (bman.updatestatusbar || hurrywarn_to <= 0.0 || hurrywarn_to > HURRYWARN_TO_BLINKING) { hurrywarn_to = HURRYWARN_TO_BLINKING; hurrywarn_state = !hurrywarn_state; if (hurrywarn_state) { font_drawbold ((gfx.res.x - strlen ("HURRY HURRY")*font[1].size.x)/2, 40, "HURRY HURRY", 1, 0, 2); font_draw ((gfx.res.x - strlen ("HURRY HURRY")*font[1].size.x)/2, 40, "HURRY HURRY", 1, 1); } else { font_drawbold ((gfx.res.x - strlen ("HURRY HURRY")*font[1].size.x)/2, 40, "HURRY HURRY", 1, 1, 2); font_draw ((gfx.res.x - strlen ("HURRY HURRY")*font[1].size.x)/2, 40, "HURRY HURRY", 1, 0); } dest.x = dest.y = 0; dest.h = 4.5 *16; dest.w = gfx.res.x; gfx_blitupdaterectadd (&dest); } } if (debug) debug_ingameinfo(); bman.updatestatusbar = 0; }; /* * keyboard handling for keys which have nothing to do with the playerkeys * before calling this function make sure keyb_loop (); was called. * * chat mode: the chatmode should only be disabled in the game mode * in the GS_wait mode the chat will always be active. */ void game_keys_loop () { if (menu != NULL) { /* delete all movement keys */ int i; for (i = 0; i < BCPK_max * 2; i++) keyb_gamekeys.state[i] = 0; } else { /* don't go into the game_keys if there is no menu displayed */ if (GT_MP_PTPM && bman.state == GS_ready && keyb_gamekeys.state[BCK_pause] && !keyb_gamekeys.old[BCK_pause]) { /* Server is starting the game */ bman.state = GS_running; net_send_servermode (); bman.updatestatusbar = 1; // force an update } if (keyb_gamekeys.state[BCK_fullscreen] && !keyb_gamekeys.old[BCK_fullscreen]) { /* Switch Fullscreen */ SDL_WM_ToggleFullScreen(gfx.screen); gfx.fullscreen = !gfx.fullscreen; bman.updatestatusbar = 1; // force an update } /* if (keys[SDLK_F9] && event.type == SDL_KEYDOWN) { // Switch Debugmode debug = !debug; bman.updatestatusbar = 1; // force an update } */ if (keyb_gamekeys.state[BCK_esc] && !keyb_gamekeys.old[BCK_esc]) { if (chat.active && (bman.state == GS_ready || bman.state == GS_running) && IS_LPLAYER2) { chat.active = 0; d_printf ("Chatmode Disabled\n"); } else game_menu_create (); } if ((GT_MP_PTPM || GT_MP_PTPS) && keyb_gamekeys.state[BCK_chat] && !keyb_gamekeys.old[BCK_chat]) { chat_setactive (1, 0); chat.changed = 1; d_printf ("Chatmode Enabled\n"); } } }; void game_loop () { SDL_Event event; int done = 0, eventstate; gfx_blitupdaterectclear (); draw_logo (); draw_field (); if (GT_MP) net_game_fillsockaddr (); SDL_Flip (gfx.screen); menu = NULL; bman.updatestatusbar = 1; // force an update timestamp = SDL_GetTicks (); // needed for time sync. d_gamedetail ("GAME START"); draw_players (); while (!done && (bman.state == GS_running || bman.state == GS_ready)) { if ((eventstate = SDL_PollEvent (&event)) != 0) switch (event.type) { case (SDL_QUIT): done = 1; bman.state = GS_quit; } /* * input handling */ keyb_loop (&event); game_keys_loop (); chat_loop (&event); if ((!IS_LPLAYER2) && (!chat.active)) chat_setactive (1, 1); restore_players_screen (); player_check (bman.p_nr); if (IS_LPLAYER2) player_check (bman.p2_nr); dead_playerani (); special_loop (); player_move (bman.p_nr); if (IS_LPLAYER2) player_move (bman.p2_nr); if (GT_MP) { player_calcpos (); network_loop (); } if (bman.state == GS_running) single_loop (); bomb_loop (); field_loop (); flitems_loop (); draw_players (); game_draw_info (); // will set the var bman.player_nr /* check if there is only one player left and the game is in multiplayer mode and if there the last dieing animation is done */ if (game_check_endgame () && bman.timeout >= 0.0f) bman.timeout = 0.0f; if ((GT_SP || GT_MP_PTPM) && bman.timeout < -GAME_OVERTIMEOUT) { d_printf ("GAME: Game Over\n"); done = 1; } stonelist_draw (); /* if there is any menu displayed do so */ if (menu != NULL) game_menu_loop (&event, eventstate); gfx_blitdraw (); s_calctimesync (); bman.timeout -= timediff; } if (menu != NULL) menu_delete (menu); gfx_blitdraw (); chat_show (-1, -1, -1, -1); d_gamedetail ("GAME END"); d_printf ("done = %d\n", done); draw_logo (); gfx_blitupdaterectclear (); SDL_Flip (gfx.screen); }; /* * check if we only one player left or only ai players are left. * check also if we there is only one team alife */ #define ENDGAME_CHECK_AGAIN 1.0f int game_check_endgame () { int res = 0; static float loop; loop -= timediff; if (loop > 0.0f && loop < ENDGAME_CHECK_AGAIN) return 0; loop = ENDGAME_CHECK_AGAIN; if (bman.gametype == GT_team) { /* * Team Mode Calculation */ int t_nr; // teamnumber int p_nr; // playernumber int h_team = 0; // how many human teams are alife int ateam = 0; // teams which are alife int h_team_last = -1; // last human team which was alife int team_last = -1; // last teams which was alift _player *p; for (t_nr = 0; t_nr < MAX_TEAMS; t_nr++) for (p_nr = 0; p_nr < MAX_PLAYERS; p_nr++) if (teams[t_nr].players[p_nr] != NULL) { p = teams[t_nr].players[p_nr]; if (PS_IS_used (p->state) && PS_IS_alife (p->state)) { if (team_last != t_nr) { team_last = t_nr; ateam++; } if ((!PS_IS_aiplayer (p->state)) && h_team_last != t_nr) { h_team++; h_team_last = t_nr; } } } if (h_team < 1 || ateam < 2) res = 1; } else if ((bman.gametype == GT_bomberman) || (map.state != MS_normal && bman.gametype == GT_deathmatch)) { int p_nr; // playernumber int h_alife = 0; // human players who are alife int alife = 0; // ai players who are alife _player *p; for (p = &players[0], p_nr = 0; p_nr < MAX_PLAYERS; p_nr++, p++) { if (PS_IS_used (p->state) && PS_IS_alife (p->state)) { alife++; if (!PS_IS_aiplayer (p->state)) h_alife++; } } if ((h_alife < 1) || (alife < 2)) res = 1; } return res; }; #undef ENDGAME_CHECK_AGAIN /* check which player won and free all unnneded data */ void game_end () { int i; int cnt_left = 0; gfx_free_players (); tileset_free (); snd_music_stop (); snd_free (); /* count the wins for the player, and if only one player * left count the points too */ cnt_left = 0; for (i = 0; i < MAX_PLAYERS; i++) if (PS_IS_used (players[i].state)) { if (PS_IS_alife (players[i].state)) { bman.lastwinner = i; cnt_left++; players[i].wins++; } } if (cnt_left == 1) players[bman.lastwinner].points += bman.players_nr_s; else bman.lastwinner = -1; /* check which team was alife */ if (bman.gametype == GT_team) { int t_nr; cnt_left = 0; for (t_nr = 0; t_nr < MAX_TEAMS; t_nr++) for (i = 0; i < MAX_PLAYERS; i++) { if (teams[t_nr].players[i] != NULL) if (PS_IS_alife(teams[t_nr].players[i]->state)) { if (bman.lastwinner != t_nr) { teams[t_nr].wins++; cnt_left++; } bman.lastwinner = t_nr; } } if (cnt_left == 1) { /* set the points */ cnt_left = 0; for (t_nr = 0; t_nr < MAX_TEAMS; t_nr++) { for (i = 0; (i < MAX_PLAYERS && teams[t_nr].players[i] != NULL); i++); if (i < MAX_PLAYERS && teams[t_nr].players[i] != NULL) cnt_left++; } teams[bman.lastwinner].points += cnt_left; } else bman.lastwinner = -1; } if (GT_SP) game_showresult (); /* check which player is now free,i.e. disconnected during the game and was playing */ for (i = 0; i < MAX_PLAYERS; i++) if ((players[i].state & PSF_used) == 0) players[i].state = 0; } /* load the images with the right scaleing */ void game_start () { int p, i; menu_displaytext ("Loading..", "Please Wait"); bman.players_nr_s = 0; for (p = 0; p < MAX_PLAYERS; p++) { if (PS_IS_used (players[p].state)) { bman.players_nr_s++; if (players[p].gfx_nr == -1) { players[p].gfx = NULL; players[p].state &= (0xff - (PSF_alife + PSF_playing)); } else { players[p].state |= PSF_alife + PSF_playing; players[p].gfx = &gfx.players[players[p].gfx_nr]; } } else players[p].state = 0; players[p].bombs_n = bman.start_bombs; players[p].range = bman.start_range; players[p].speed = bman.start_speed; players[p].collect_shoes = 0; players[p].special.type = SP_nothing; players[p].m = 0; players[p].old.x = 0; players[p].old.y = 0; bman.updatestatusbar=1; players[p].frame = 0.0f; players[p].d = 0; players[p].pos.x = -1; players[p].pos.y = -1; players[p].tunnelto = 0.0f; /* all types of illnes turn them off */ for (i = 0; i < PI_max; i++) players[p].ill[i].to = 0.0f; // reset bombs for (i = 0; i < MAX_BOMBS; i++) { players[p].bombs[i].state = BS_off; players[p].bombs[i].ex_nr = -1; players[p].bombs[i].speed = 0; players[p].bombs[i].dest.x = 0; players[p].bombs[i].dest.y = 0; players[p].bombs[i].mode = BM_normal; players[p].bombs[i].id.p = p; players[p].bombs[i].id.b = i; } } flitems_reset (); init_map_tileset (); tileset_load (map.tileset, -1, -1); gfx_load_players (gfx.block.x, gfx.block.y); snd_load (map.tileset); snd_music_start (); map.state = MS_normal; bman.timeout = bman.init_timeout; s_calctimesync (); // to clean up the timesyc s_calctimesync (); // data run this twice if (GT_MP_PTPM) net_send_servermode (); }; /* * Show results of the game * show the diffrent screens one for players and one for teams */ /* Teamplay */ #define SHOWRESULT_TEAMHEAD 24 #define SHOWRESULT_TEAMPLAYER 16 #define SHOWRESULT_TEAMPLAYERWIDTH 150 static void game_showresultteam () { int i, t_nr, p_nr; // counter for teams and players struct { _team *team; // pointer to the team _player *pl[MAX_PLAYERS]; // players in the team (sorted) int cnt; } tdata[MAX_TEAMS+1]; // hold some team informations (sorted) int t_count = 0, p_maxcount = 0, p_sumcount = 0; int sx, sy, p_y, p_x , dx, dy, col, x; SDL_Rect dest, src; char text[255]; /* sort all teams */ for (t_nr = 0; t_nr < MAX_TEAMS; t_nr++) { tdata[t_nr].team = NULL; tdata[t_nr].cnt = 0; } for (t_nr = 0; t_nr < MAX_TEAMS; t_nr++) { for (p_nr = 0; (p_nr < MAX_PLAYERS && teams[t_nr].players[p_nr] == NULL); p_nr++); if (p_nr < MAX_PLAYERS && teams[t_nr].players[p_nr] != NULL) { tdata[t_count].team = &teams[t_nr]; i = t_count; while (i > 0 && (tdata[i-1].team->wins < teams[t_nr].wins || (tdata[i-1].team->wins == teams[t_nr].wins && tdata[i-1].team->points < teams[t_nr].points))) { tdata[i].team = tdata[i-1].team; i--; tdata[i].team = &teams[t_nr]; } t_count++; } } /* sort all players dependsing on the number of wins they have */ for (t_nr = 0; t_nr <= t_count; t_nr++) for (p_nr = 0, tdata[t_nr].cnt = 0; p_nr < MAX_PLAYERS; p_nr++) { if (t_nr < t_count) { if (tdata[t_nr].team->players[p_nr] != NULL && PS_IS_used (tdata[t_nr].team->players[p_nr]->state)) { tdata[t_nr].pl[tdata[t_nr].cnt] = tdata[t_nr].team->players[p_nr]; i = tdata[t_nr].cnt; while (i > 0 && (tdata[t_nr].pl[i-1]->wins < tdata[t_nr].team->players[p_nr]->wins || (tdata[t_nr].pl[i-1]->wins == tdata[t_nr].team->players[p_nr]->wins && tdata[t_nr].pl[i-1]->points < tdata[t_nr].team->players[p_nr]->points))) { tdata[t_nr].pl[i] = tdata[t_nr].pl[i-1]; i--; tdata[t_nr].pl[i] = tdata[t_nr].team->players[p_nr]; } tdata[t_nr].cnt++; } } else { /* sort all players also the ones which are not in a team */ if (players[p_nr].team_nr == -1 && PS_IS_used (players[p_nr].state)) { tdata[t_nr].pl[tdata[t_nr].cnt] = &players[p_nr]; i = tdata[t_nr].cnt; while (i > 0 && (tdata[t_nr].pl[i-1]->wins < players[p_nr].wins || (tdata[t_nr].pl[i-1]->wins == players[p_nr].wins && tdata[t_nr].pl[i-1]->points < players[p_nr].points))) { tdata[t_nr].pl[i] = tdata[t_nr].pl[i-1]; i--; tdata[t_nr].pl[i] = &players[p_nr]; } tdata[t_nr].cnt++; } } } /* check the max number of players in one team and number of all players */ for (t_nr = 0, p_maxcount = 0; t_nr <= t_count; t_nr++) /* t_count + 1 */ if (p_maxcount < tdata[t_nr].cnt) p_maxcount = tdata[t_nr].cnt; for (p_sumcount = 0, p_nr = 0; p_nr < MAX_PLAYERS; p_nr++) if (PS_IS_used (players[p_nr].state)) p_sumcount++; /* calculate the best view */ p_x = dx = dy = 0; do { p_x++; p_y = 0; // calc. again for this setting for (t_nr = 0; t_nr <= t_count; t_nr++) { p_y += ceil ((float)(((float) tdata[t_nr].cnt) / ((float)p_x))); } if (p_y == 0) p_y = 1; dy = (gfx.res.y - 100 - (SHOWRESULT_TEAMHEAD * (t_count + 1))) / p_y; } while (dy < SHOWRESULT_TEAMPLAYER); if (dy > 2*SHOWRESULT_TEAMPLAYER) dy = 2*SHOWRESULT_TEAMPLAYER; /* draw everything */ sy = (gfx.res.y - (SHOWRESULT_TEAMHEAD * (t_count + 1) + dy * p_y)) / 2; for (t_nr = 0; t_nr <= t_count; t_nr++) { if (t_nr < t_count) /* normal teams */ sprintf (text, "%s Victorys %d (%d)", tdata[t_nr].team->name, tdata[t_nr].team->wins, tdata[t_nr].team->points); else sprintf (text, "Players without a Team"); sx = (gfx.res.y - strlen (text) * font[0].size.x) / 2; font_drawbold (sx, sy+3, text, 0, COLOR_brown, 1); font_draw (sx, sy+3, text, 0, COLOR_yellow); sy += SHOWRESULT_TEAMHEAD; dx = (gfx.res.x - 40) / p_x; sx = 20 + (dx - SHOWRESULT_TEAMPLAYERWIDTH)/2; for (col = 0, p_nr = 0; p_nr < tdata[t_nr].cnt; p_nr++) { if (col == 0 || col >= p_x) { if (col >= p_x) sy += dy; col = 0; x = sx; } dest.x = x; dest.y = sy; src.w = dest.w = tdata[t_nr].pl[p_nr]->gfx->small_image->w; src.h = dest.h = tdata[t_nr].pl[p_nr]->gfx->small_image->h; src.x = 0; src.y = 0; gfx_blit (tdata[t_nr].pl[p_nr]->gfx->small_image, &src, gfx.screen, &dest, 1); sprintf (text, "%s(%d/%d)", tdata[t_nr].pl[p_nr]->name, tdata[t_nr].pl[p_nr]->wins, tdata[t_nr].pl[p_nr]->points); font_draw (x + GFX_SMALLPLAYERIMGSIZE_X*2, sy + 2, text, 0, 0); x += dx; col++; } gfx_blitdraw (); sy += dy; } } #undef SHOWRESULT_TEAMHEAD #undef SHOWRESULT_TEAMPLAYER #undef SHOWRESULT_TEAMPLAYERWIDTH /* Bomberman/Deathmatch Version Play */ #define SHOWRESULT_WIDTH 150 #define SHOWRESULT_HEIGHT 80 static void game_showresultnormal () { char text[255]; int i, p, x, y, pl_cnt = 0, pl_x, pl_y, // player in a row/col dx, dy, // distance sx, sy, px; // start view and position SDL_Rect dest, src; _player *pl[MAX_PLAYERS]; /* Sort the playerlist */ for (p = 0, pl_cnt = 0; p < MAX_PLAYERS; p++) if (PS_IS_used (players[p].state)) { pl[pl_cnt] = &players[p]; i = pl_cnt; while (i > 0 && (pl[i-1]->wins < players[p].wins || (pl[i-1]->wins == players[p].wins && pl[i-1]->points < players[p].points))) { pl[i] = pl[i-1]; i--; pl[i] = &players[p]; } pl_cnt++; } /* calc the best view and start point */ pl_x = 0; do { pl_x++; pl_y = ceil ((float)(((float) pl_cnt) / ((float)pl_x))); dy = (gfx.res.y - 100) / pl_y; } while (dy < SHOWRESULT_HEIGHT); dx = (gfx.res.x - 40) / pl_x; x = sx = 20 + (dx - SHOWRESULT_WIDTH)/2; y = sy = 60 + (dy - SHOWRESULT_HEIGHT)/2; px = 0; d_printf ("game_showresultnormal: pl_x:%d, pl_y:%d, dx:%d, dy:%d\n", pl_x, pl_y, dx, dy); /* draw the playerlist */ for (i = 1, p = 0; p < pl_cnt; p++) { if (PS_IS_used (pl[p]->state)) { if (PS_IS_alife (pl[p]->state)) { font_drawbold (x + GFX_MENUPLAYERIMGSIZE_X, y - 10, pl[p]->name, 0, COLOR_brown, 1); font_draw (x + GFX_MENUPLAYERIMGSIZE_X, y - 10, pl[p]->name, 0, COLOR_yellow); } else font_draw (x + GFX_MENUPLAYERIMGSIZE_X, y - 10, pl[p]->name, 0, COLOR_gray); sprintf (text, "%3d (%3d)", pl[p]->wins, pl[p]->points); font_draw (x + GFX_MENUPLAYERIMGSIZE_X, y + 6, text, 0, 0); dest.x = x; dest.y = y - 16; src.w = dest.w = pl[p]->gfx->menu_image->w; src.h = dest.h = pl[p]->gfx->menu_image->h; src.x = 0; src.y = 0; gfx_blit (pl[p]->gfx->menu_image, &src, gfx.screen, &dest, 1); /* setup the new position */ y += (dy / pl_x); x += dx; px++; if (px >= pl_x) { px = 0; x = sx; } } } } #undef SHOWRESULT_HEIGHT #undef SHOWRESULT_WIDTH void game_showresult () { char text[255]; SDL_Event event; Uint8 *keys; int done = 0, keypressed = 0, x, y; gfx_blitdraw (); draw_logo (); strcpy (text, "Game Result"); x = (gfx.res.x - (font[2].size.x * strlen (text)) - 64) / 2; y = 0; font_drawbold (x, y, text, 2, 6, 2); font_draw (x, y, text, 2, 5); y += font[2].size.x; strcpy (text, "[CTRL],[RETURN] or [STRG] for another game"); x = (gfx.res.x - (font[1].size.x * strlen (text)) - 64) / 2; font_drawbold (x, gfx.res.y - (2*font[0].size.y) - 2, text, 0, COLOR_brown, 1); font_draw (x, gfx.res.y - (2*font[0].size.y) - 2, text, 0, COLOR_yellow); strcpy (text, "or [ESC] to leave the game."); x = (gfx.res.x - (font[1].size.x * strlen (text)) - 64) / 2; font_drawbold (x, gfx.res.y - font[0].size.y - 2, text, 0, COLOR_brown, 1); font_draw (x, gfx.res.y - font[0].size.y - 2, text, 0, COLOR_yellow); if (bman.gametype == GT_team) game_showresultteam (); else game_showresultnormal (); gfx_blitdraw (); SDL_Flip (gfx.screen); while (!done && bman.state != GS_quit) { /* do the keyboard handling */ if (SDL_PollEvent (&event) != 0) switch (event.type) { case (SDL_QUIT): bman.state = GS_quit; bman.p_nr = -1; done = 1; } keys = SDL_GetKeyState (NULL); if (keys[SDLK_ESCAPE] && event.type == SDL_KEYDOWN) { /* we want to quit */ done = 1; bman.p_nr = -1; keypressed = 1; bman.state = GS_startup; } if ((keys[SDLK_RETURN] || keys[SDLK_LCTRL] || keys[SDLK_RCTRL]) && (!keypressed) && (event.type = SDL_KEYDOWN)) { done = 1; keypressed = 1; } if (keys[SDLK_F8] && event.type == SDL_KEYDOWN) { /* Switch Fullscreen */ SDL_WM_ToggleFullScreen(gfx.screen); gfx.fullscreen = !gfx.fullscreen; bman.updatestatusbar = 1; // force an update } if (event.type == SDL_KEYUP) keypressed = 0; else if (event.type == SDL_KEYDOWN) keypressed = 1; s_delay (25); } if (bman.state != GS_quit && bman.state != GS_startup) bman.state = GS_running; }; /* * create the in game menu */ void game_menu_create () { if (menu != NULL) return; menu = menu_new ("Gamemenu", 300, 150); menu_create_button (menu, "Back to the Game", -1, 50, 200, 1); if (GT_SP || GT_MP_PTPM) menu_create_button (menu, "End this Round", -1, 80, 200, 2); menu_create_button (menu, "Quit the Game", -1, 110, 200, 3); menu_focus_id (menu, 1); menu->looprunning = 1; }; /* * in game menu_loop, will called every game loop. * As long as this menu is displayed the gamekeys will not work. * * the drawings will be done from the main loop. So we won't * have to draw anything on our own. * * Pressing ESC will bring you back to the game. */ void game_menu_loop (SDL_Event *event, int eventstate) { int done; if (menu == NULL) return; menu_draw (menu); done = menu_event_loop (menu, event, eventstate); /* * check if one of the buttons was pressed */ if (done != 0) { if (menu->focus->id == 2 && (GT_MP_PTPM || GT_SP)) { /* End Round */ bman.timeout = -GAME_OVERTIMEOUT; } else if (menu->focus->id == 3) /* End Game */ bman.state = GS_quit; else { /* Quit Menu */ menu_delete (menu); menu = NULL; gfx_blitdraw (); draw_field (); } } };