/* $Id: game.c,v 1.45 2003/07/26 02:43:21 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" extern int blitdb_nr, blitrects_nr; static Uint32 timediff, timediff1; void game_draw_info () { int i, x, j; char text[255]; char scrtext[255]; SDL_Rect src, dest; if (bman.updatestatusbar) { redraw_logo (0, 0, gfx.res.x, (4.5 * 16)); bman.updatestatusbar = 0; dest.x = dest.y = 0; dest.h = 4.5 *16; dest.w = gfx.res.x; gfx_blitupdaterectadd (&dest); bman.players_nr = 0; /* 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 ((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 (!PS_IS_alife (bman.players[i].state)) { // Player is dead if ((bman.players[i].state & PSF_used) != PSF_used) font_setcolor (128, 128, 128, 0); else font_setcolor (0, 0, 128, 0); } else { // players is alife font_setcolor (128, 128, 255, 0); bman.players_nr++; } font_draw (x, j, scrtext, 0); x = x + 170; if (x >= gfx.res.x - (120 + 170)) { x = 0; j = j + 1.5 * font[0].size.x; } } font_setcolor (255, 255, 255, 0); x = gfx.res.x - 120; sprintf (text, "Bombs: %2d", bman.players[bman.p_nr].bombs_n); font_draw (x, 0, text, 0); sprintf (text, "Range: %2d", bman.players[bman.p_nr].range); font_draw (x, 16, text, 0); sprintf (text, "Speed: %2d", bman.players[bman.p_nr].speed); font_draw (x, 32, text, 0); if (bman.players[bman.p_nr].special.type != 0) { dest.x = x - 32; dest.y = 16; dest.w = gfx.smal_special[bman.players[bman.p_nr].special.type - 1]->w; dest.h = gfx.smal_special[bman.players[bman.p_nr].special.type - 1]->h; SDL_BlitSurface (gfx.smal_special[bman.players[bman.p_nr].special.type - 1], NULL, gfx.screen, &dest); } if (bman.state == GS_ready && GT_MP_PTPM) font_draw (100, 32, "Press F4 to start the game", 0); else if (bman.state == GS_ready) font_draw (100, 32, "Waiting for the Server to Start", 0); } if (chat.visible == 0 && GT_MP_PTP) 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 gfx_blitupdaterectclear (); draw_logo (); draw_field (); if (GT_MP_PTP) net_game_fillsockaddr (); SDL_Flip (gfx.screen); 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 (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 (bman.p_nr); key_bomb = 1; } else key_bomb = 0; if ((keys[SDLK_LSHIFT] || keys[SDLK_RSHIFT]) && bman.players[bman.p_nr].special.type) { special_use (bman.p_nr); } } else if (GT_MP_PTPM && keys[SDLK_F4] && event.type == SDL_KEYDOWN) { /* Server is starting the game */ bman.state = GS_running; net_send_servermode (); bman.updatestatusbar = 1; // force an update } if (event.key.keysym.sym == SDLK_ESCAPE && event.type == SDL_KEYDOWN) { bman.state = GS_startup; done = 1; } chat_loop (&event); restore_players_screen (); dead_playerani (); player_ilness_loop (bman.p_nr); special_loop (); if ((bman.players[bman.p_nr].state & PSFM_alife) == PSFM_alife) move_player (bman.p_nr); if (GT_MP_PTP) player_calcpos (); 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 */ bomb_loop (); field_animation (); draw_players (); game_draw_info (); /* 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 ((bman.players_nr < 2 && (GT_MP_PTP || (bman.gametype == GT_single && bman.ai_players > 0))) || (bman.gametype == GT_single && bman.ai_players == 0 && bman.players_nr < 1)) gameovertimeout--; if (gameovertimeout <= 0) { d_printf ("GAME: Game Over 'Cause only one or none anymore alife\n"); done = 1; } stonelist_draw (); gfx_blitdraw (); // 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 (); } timediff1 = timeloop1 - timestamp; timestamp = timeloop1; } chat_show (-1, -1, -1, -1); d_gamedetail ("GAME END"); d_printf ("done = %d\n", done); }; /* check which player won and unload all data */ void game_end () { int i; gfx_free_players (); tileset_free (); snd_free (); /* 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; } } if (!GT_MP_PTP) 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 ((bman.players[i].state & PSF_used) == 0) bman.players[i].state = 0; } /* load the images with the right scaleing */ void game_start () { menu_displaytext ("Loading..", "Please Wait", 32, 128, 32); tileset_load (map.tileset); gfx_load_players (gfx.block.x, gfx.block.y); snd_load (map.tileset); }; /* shor result of the game */ void game_showresult () { SDL_Rect dest, src; char text[255]; SDL_Event event; Uint8 *keys; int done = 0, keypressed = 0, x, y, i, p; menu_displaytext ("Loading..", "Please Wait", 32, 128, 32); dest.x = dest.y = 0; dest.w = gfx.res.x; dest.h = gfx.res.y; gfx_load_players (64, 64); draw_logo (); strcpy (text, "Game Result"); x = (gfx.res.x - (font[2].size.x * strlen (text)) - 64) / 2; y = 0; font_setcolor (128, 128, 0, 2); font_drawbold (x, y, text, 2, 2); font_setcolor (255, 255, 128, 2); font_draw (x, y, text, 2); y += font[2].size.x; for (i = 0, p = 0; p < MAX_PLAYERS; p++) if (PS_IS_alife (bman.players[p].state)) i++; if (i == 1) strcpy (text, "Game Over"); else strcpy (text, "Draw Game"); x = (gfx.res.x - (font[2].size.x * strlen (text)) - 64) / 2; font_setcolor (128, 128, 0, 2); font_drawbold (x, y, text, 2, 2); font_setcolor (255, 255, 128, 2); font_draw (x, y, text, 2); y += font[2].size.x + 8; strcpy (text, "Hit [CTRL], [RETURN] or [STRG]"); x = (gfx.res.x - (font[1].size.x * strlen (text)) - 64) / 2; font_setcolor (128, 128, 0, 1); font_drawbold (x, gfx.res.y - font[1].size.y - 2, text, 1, 1); font_setcolor (255, 255, 128, 1); font_draw (x, gfx.res.y - font[1].size.y - 2, text, 1); for (i = 1, p = 0; p < MAX_PLAYERS; p++) { if (PS_IS_used (bman.players[p].state)) { if (!i) { i = 1; x = (gfx.res.x / 2) + 16; } else if (i) { i = 0; y = y + 80; x = 16; } font_setcolor (128, 128, 128, 0); font_drawbold (x + 80, y + 4, bman.players[p].name, 0, 2); if (PS_IS_alife (bman.players[p].state)) font_setcolor (255, 255, 0, 0); else font_setcolor (196, 196, 196, 0); font_draw (x + 80, y + 4, bman.players[p].name, 0); sprintf (text, "%3d", bman.players[p].wins); font_draw (x + 80 + (LEN_PLAYERNAME+2) * font[0].size.x, y + 4, text, 0); sprintf (text, "%3d", bman.players[p].points); font_draw (x + 80 + (LEN_PLAYERNAME+5) * font[0].size.x, y + 4, text, 0); dest.x = x; dest.y = y; src.w = dest.w = bman.players[p].gfx->ani.w; src.h = dest.h = bman.players[p].gfx->ani.h; src.x = bman.players[p].gfx->ani.w * down; src.y = 0; } } gfx_blitdraw (); SDL_Flip (gfx.screen); gfx_free_players (); while (!done) { /* 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 (event.type == SDL_KEYUP) keypressed = 0; else if (event.type == SDL_KEYDOWN) keypressed = 1; s_delay (25); } };