/* game.c - procedures for the game. */ #include #include #include "bomberclone.h" #include "gfx.h" #include "network.h" #include "packets.h" #include "chat.h" extern int UpdateRects_nr; static Uint32 timediff; void game_draw_info () { int i, x, j, gfx_oldRects; char text[255]; char scrtext[255]; SDL_Rect src, dest; redraw_logo (0, 0, gfx.res.x, 3*16); gfx_AddUpdateRect (0,0, gfx.res.x, 3*16); gfx_oldRects = UpdateRects_nr; bman.players_nr = 0; /* draw Player names */ if (GT_MP_PTP) { for (x = 0, j = 0, i = 0; i < MAX_PLAYERS; i++) if ((bman.players[i].state & PSFM_used) != 0) { if (bman.players[i].gfx_nr != -1 && PS_IS_used (bman.players[i].state)) { src.x = 3 * bman.players[i].gfx->smal_size.x; src.y = 0; src.w = dest.w = bman.players[i].gfx->smal_size.x; src.h = dest.h = bman.players[i].gfx->smal_size.y; dest.x = x; dest.y = j - 4; SDL_BlitSurface (bman.players[i].gfx->smal_image, &src, gfx.screen, &dest); } sprintf (scrtext, "%10s:%2d", bman.players[i].name, bman.players[i].points); if ((bman.players[i].state & PSFM_alife) != PSFM_alife) { // Player is dead draw_text (x, j, scrtext, 0); if ((bman.players[i].state & PSF_used) != PSF_used) draw_text (x, j, "-------------", 1); } else { // players is alife draw_text (x, j, scrtext, 1); bman.players_nr++; } x = x + 170; if (x >= gfx.res.x - (120 + 170)) { x = 0; j = j + 14; } } } x = gfx.res.x - 120; sprintf (text, "Bombs: %2d", bman.players[bman.p_nr].bombs_n); draw_text (x, 0, text, 1); sprintf (text, "Range: %2d", bman.players[bman.p_nr].range); draw_text (x, 16, text, 1); sprintf (text, "Speed: %2d", bman.players[bman.p_nr].speed); draw_text (x, 32, text, 1); if (bman.state == GS_ready && GT_MP_PTPM) draw_text (100, 32, "Press F4 to start the game", 1); else if (bman.state == GS_ready) draw_text (100, 32, "Waiting for the Server to Start", 1); gfx_AddUpdateRect (100, 32, gfx.res.x - 100, 16); redraw_logo (0, gfx.res.y - gfx.font.size.y, gfx.res.x, gfx.res.y); for (x = 0; x < bman.fieldsize.x; x++) draw_stone (x, bman.fieldsize.y-1); if (debug) { /* do some debug informations on the screen */ sprintf (text, "NET_STAT: ["); for (i = 0 ; i < MAX_PLAYERS; i++) sprintf (text, "%s%3d ", text, bman.players[i].net.pkgopt.send_set); text[strlen(text)+1] = 0; text[strlen(text)] = ']'; sprintf (text, "%s GFX_RECTS:%d", text, UpdateRects_nr); draw_text (0, gfx.res.y - (gfx.font.size.y << 1), text, 1); sprintf (text, "TILESET: %s Timediff: %d", gfx.tileset, timediff); draw_text (0, gfx.res.y - gfx.font.size.y, text, 1); gfx_AddUpdateRect (0, gfx.res.y - (gfx.font.size.y << 1), gfx.res.x, gfx.font.size.y << 1); } if (chat.visible == 0) { SDL_Flip (gfx.screen); chat_show (4, 3*16, gfx.res.x - 4, gfx.offset.y); } }; void game_loop () { SDL_Event event; Uint8 *keys; int done = 0; Uint32 timeloop1; int gameovertimeout = TIME_FACTOR * 5; // gameovertimeout unsigned char key_bomb = 0; // last state of the bomb key draw_logo (); draw_field (); if (GT_MP_PTP) net_game_fillsockaddr (); SDL_Flip (gfx.screen); timestamp = SDL_GetTicks (); // needed for time sync. d_gamedetail ("GAME START"); while (!done && (bman.state == GS_running || bman.state == GS_ready)) { if (SDL_PollEvent (&event) != 0) switch (event.type) { case (SDL_QUIT): done = 1; bman.state = GS_quit; } /* keyboard handling */ keys = SDL_GetKeyState (NULL); /* only do movements if we're alife and GS_running */ if ((bman.players[bman.p_nr].state & PSFM_alife) == PSFM_alife && bman.state == GS_running) { if (keys[SDLK_UP]) { bman.players[bman.p_nr].d = up; bman.players[bman.p_nr].m = 1; } if (keys[SDLK_DOWN]) { bman.players[bman.p_nr].d = down; bman.players[bman.p_nr].m = 1; } if (keys[SDLK_RIGHT]) { bman.players[bman.p_nr].d = right; bman.players[bman.p_nr].m = 1; } if (keys[SDLK_LEFT]) { bman.players[bman.p_nr].d = left; bman.players[bman.p_nr].m = 1; } if (keys[SDLK_LCTRL] || keys[SDLK_RCTRL]) { if (key_bomb == 0) player_drop_bomb (); key_bomb = 1; } else key_bomb = 0; if (keys[SDLK_LSHIFT] || keys[SDLK_RSHIFT]) { d_printf ("not in use yet\n"); } } else if (GT_MP_PTPM && keys[SDLK_F4] && event.type == SDL_KEYDOWN) { /* Server is starting the game */ bman.state = GS_running; net_send_servermode (); } if (event.key.keysym.sym == SDLK_ESCAPE && event.type == SDL_KEYDOWN) { bman.state = GS_startup; done = 1; } chat_loop (&event); restore_players_screen (); restore_bomb_screen (); player_ilness_loop (); if ((bman.players[bman.p_nr].state & PSFM_alife) == PSFM_alife) move_player (); player_calcpos (); dead_playerani (); /* we need it to draw dead players */ if (bman.gametype != GT_single) network_loop (); else single_loop (); /* this will even set the variable "bman.player_nr" to let us know how much Players are still left */ game_draw_info (); bomb_loop (); draw_players (); gfx_UpdateRects (); /* 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 ((GT_MP_PTPM) && bman.players_nr < 2) gameovertimeout--; /* check if we died and we are in single mode and the animation is done */ if (bman.gametype == GT_single && !PS_IS_alife(bman.players[bman.p_nr].state)) gameovertimeout--; if (gameovertimeout <= 0) { d_printf ("GAME: Game Over 'Cause only one or noone anymore alife\n"); done = 1; } // calculate time sync. timeloop1 = SDL_GetTicks (); timediff = timeloop1 - timestamp; // only for debugging needed while (timeloop1 - timestamp >= 0 && timeloop1 - timestamp < 20) { s_delay (20 - (timeloop1 - timestamp) - 1); timeloop1 = SDL_GetTicks (); } timestamp = timeloop1; } chat_show (-1, -1, -1, -1); d_gamedetail ("GAME END"); d_printf ("done = %d\n", done); }; /* check which player won */ void game_end () { int i; /* count the points */ for (i = 0; i < MAX_PLAYERS; i++) if (PS_IS_used (bman.players[i].state)) { if (PS_IS_alife (bman.players[i].state)) { bman.lastwinner = i; bman.players[i].wins++; bman.players[i].points += bman.players_nr_s; } } /* check which player is now free ,i.e. disconnected during the game and was playing */ for (i = 0; i < MAX_PLAYERS; i++) if ((bman.players[i].state & PSF_used ) == 0) bman.players[i].state = 0; }