Logo Search packages:      
Sourcecode: xblast version File versions  Download package

main.c

/*
 * Program XBLAST V2.5.17 or higher
 * (C) by Oliver Vogel (e-mail: vogel@ikp.uni-koeln.de)
 * May 14, 1999
 * started August 1993
 *
 * File: main.c 
 * gameplay and main programm
 *
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published
 * by the Free Software Foundation; either version 2; or (at your option)
 * any later version
 *
 * This program is distributed in the hope that it will be entertaining,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
 * MERCHANTABILTY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
 * Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.
 * 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * $Id: main.c,v 1.5 1999/08/07 20:01:58 xblast Exp $
 * $Log: main.c,v $
 * Revision 1.5  1999/08/07 20:01:58  xblast
 * Sound for morph bomb implemented
 *
 * Revision 1.4  1999/05/14 21:00:24  xblast
 * now using current e-mail in credits
 *
 * Revision 1.3  1999/03/21 13:47:37  xblast
 * Experimental score functions removed
 *
 * Revision 1.2  1998/10/18 12:30:04  xblast
 * Morphing Bomb extra
 *
 * Revision 1.1  1998/01/03 14:10:37  xblast
 * Initial revision
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>

#define _MAIN_C
#include "include.h"
#include "mytypes.h"
#include "const.h"
#include "image.h"
#include "patchlev.h"
#include "intro.h"
#include "graphics.h"
#include "func.h"
#include "maze.h"
#include "map.h"
#include "bomb.h"
#include "data.h"
#include "event.h"
#include "shrink.h"
#include "status.h"
#include "main.h"
#include "setup.h"
#include "util.h"
#include "pipe.h"
#include "info.h"
#include "sprite.h"
#include "demo.h"
#include "player.h"

#ifdef XBLAST_SOUND
#include "sound.h"
#endif

/* 
 * some constants 
 */

#define MIN_RANGE 2
#define EXTRA_RETRY 4

/*
 * local types
 */
typedef struct {
  int level;
  int value;
} LevelField;

/* 
 * local variables 
 */
/* Player Stats */
static XBConfig Config;
static XBSettings Setup;
static int num_player;
static int game_mode;
#ifdef DEBUG
static XBDebug Debug;
#endif

/* special functions */
static void (*special_init_function)();
static void (*special_game_function)();
static void (*special_key_function)();
#if 1
void (*special_extra_function)();
#endif

/*
 * local variables
 */
static int num_disp;
static int pause_status = -1;
static int active_player;
static int last_team;
static int level;
static int num_victories = 0;
static void (*sound_function)();


/*
 * global variables 
 */
int game_time;
int FrameTime;


/*
 * public function exit_prg
 */
#ifdef __STDC__
void
exit_prg (int status)
#else
void
exit_prg (status)
     int status;
#endif
{
  /* close connection to X-Server */
  fprintf(stderr, "Disconnecting from X-server.\n");
  finish_display();

#ifdef XBLAST_SOUND
  /* close connection to sound server */
  if (Config.com_mode != CM_Child) {
    fprintf(stderr, "Shutting down sound server.\n");
    stop_sound_server();
  };
#endif
  fprintf(stderr, "Quit!\n");
  exit(status);
}

/* 
 * local function bm_fatal 
 */
#ifdef __STDC__
static void 
bm_fatal (char *text,
        char *prog)
#else
static void 
bm_fatal (text,prog)
     char *text,*prog;
#endif
{
  fprintf(stderr,"ERROR : %s.\n",text);
  fprintf(stderr,"Type %s -? for help\n",prog); 
  exit_prg(2);
}


/*
 * public function setup_special_funcs
 */
#ifdef __STDC__
void
setup_funcs (BMFuncData *cur_level)
#else
void
setup_funcs (cur_level)
  BMFuncData *cur_level;
#endif
{
  /* set info */
  set_info_func(cur_level);
  /* set funcs */
  special_init_function = cur_level->init_func;
  special_game_function = cur_level->game_func;
  special_extra_function = cur_level->extra_func;
  special_key_function = cur_level->key_func;
}



/*
 * local function: cmp_level_field
 */
#ifdef __STDC__
static int 
cmp_level_field (const void *a,
             const void *b)
#else
static 
int cmp_level_field (a, b)
  void *a, *b;
#endif
{
  return (((LevelField *)a)->value - ((LevelField *)b)->value);
}



/* 
 * after one game 
 */
#ifdef __STDC__
static void 
level_end (void)
#else
static void 
level_end ()
#endif
{
  static char *msg_oot  = "Out Of Time";
  static char *msg_draw = "Draw Game";
  char *Message;
  BMPlayer *ps;
  int active_teams = FALSE;
  int player, count;

  /* draw winning players (if any) */
  for (ps = player_stat; ps < player_stat + num_player; ps++) {
    if (ps->dying) {
      ps->lives --;
    }
    if (ps->lives) {
      active_teams = TRUE;
      set_sprite_mode (ps->sprite, SPM_MAPPED);
      set_sprite_anime (ps->sprite, SpriteWinner);
    }
  }
  
  /* determine game result */
  if (game_time >= (GAME_TIME-1)) {
    /* This game was out of time */
    last_team = 2*MAX_PLAYER;
    Message = msg_oot;
    /* print statistics */
    if (Setup.print_stat) {
      printf("LevelStat {%s} {%s} {", get_level_name(level), "Out Of Time");
      for (player =0; player < num_player; player ++) {
      printf(" {%s} ",p_string[player].name);
      }
      printf("}\n");
      fflush(stdout);
    }
  } else {
    /* either draw or win game */
    if (active_teams) {
      /* one player/team has won */
      last_team = 2*MAX_PLAYER;
      for (ps = player_stat; ps < player_stat + num_player; ps++) {
      if (ps->lives) {
        last_team = ps->team;
      }
      }
      Message = p_string[last_team].winlevel;
      /* print statistics */
      if (Setup.print_stat)  {
      printf("LevelStat {%s} {%s} {", get_level_name(level), 
             p_string[last_team].name);
      for (player =0; player < num_player; player ++) {
        printf(" {%s} ",p_string[player].name);
      }
      printf("}\n");
      }
    } else {
      /* draw game */
      last_team = 2*MAX_PLAYER;
      Message = msg_draw;
      /* print statistics */
      if (Setup.print_stat) {
      printf("LevelStat {%s} {%s} {", get_level_name(level), "Draw Game");
      for (player =0; player < num_player; player ++) {
        printf(" {%s} ",p_string[player].name);
      }
      printf("}\n");
      }
    }
  }
  
  /* add victories for player and team mates */
  for (ps = player_stat; ps < player_stat + num_player; ps++) {
    if (ps->team == last_team) {
      ps->victories ++;
      num_victories = MAX(num_victories, ps->victories);
    }
  }
    
  count = 0;
  do {
    if (0 == (count % 16)) {
      if (0 == (count % 32)) {
      set_message (Message, TRUE);
      } else {
      set_message ("Press Space", TRUE);
      }
    }
    other_event();
    count ++;
  } while ((Config.record_mode != RM_PLAYBACK) && 
         (!wait_eval_keys(num_player)) );
  
  fade_out();
}





/*
 * local function config_forked_game
 *
 * setup controls for forked game mode
 */
#ifdef __STDC__
static void 
config_forked_game (void)
#else
static void 
config_forked_game ()
#endif
{
  int disp, np, p1, p2, flag;
#ifndef DEBUG
  int p3;
#endif

  /* set player display link to "none" */
  if (Config.record_mode != RM_PLAYBACK) {
    disp = SPM_UNMAPPED;
  } else {
    disp = SPM_MAPPED;
  }
  for (p1 = 0; p1 <num_player; p1++) {
    player_stat[p1].disp = disp;
  }
  if (game_mode & GM_Double) {
    for (p1 = 0; p1 <num_player; p1++) {
      player_stat[p1 + num_player].disp = disp;
    }
  }
  
  /* set communication to normal in the case we only have one display */
  set_event_communication(CM_None, Config.record_mode, 0, 0);
  set_setup_communication(CM_None);
  
  /* fork mode */
  for (disp=0; disp < num_disp; disp ++) {
    /* find first player for display */
    for (p1 = 0; (p1<num_player) && (Config.pl_at_disp[p1] != disp) ; p1++);
    if (p1 == num_player) {
      fprintf(stderr, "Oops no player for display %d\n",disp);
      exit_prg(1);
    }
    /* set 2nd player for double mode */
    if (game_mode & GM_Double) {
      p2 = p1 + num_player;
      np = 2;
    }
    /* look for optional second one */
    for (p2 = p1+1; (p2<num_player) && (Config.pl_at_disp[p2] != disp) ; p2++);
    /* fork if we are not in the first display */
    if (disp == 0) {
      flag = 0;
    } else {
      flag = create_child();
    }
    
    /* check number of players */
    if (p2 < num_player) {
      /* only one double team per display */
      if (game_mode & GM_Double) {
#ifdef DEBUG
      p2 = p1 + num_player;
#else
      if (Config.record_mode == RM_PLAYBACK) {
        p2 = p1 + num_player;
      } else {
        fprintf(stderr, "Error: 2 Teams for Display %s\n", 
              Config.display[disp]);
        exit_prg(1);
      }
#endif
      }
      /* two player or more */
      np = 2;
#ifndef DEBUG
      if (Config.record_mode != RM_PLAYBACK) {
      /* look for forbidden third one */
      for (p3=p2+1; (p3<num_player)&&(Config.pl_at_disp[p3]!=disp) ; p3++);
      if (p3 < num_player) {
        fprintf(stderr, "Error: 3 players for Display %s\n", 
              Config.display[disp]);
        exit_prg(1);
      }
      }
#endif
    } else {
      /* one player */
      np = 1;
      p2 = p1;
    }

    if (!flag) {
      Config.disp_player.num = np;
      Config.disp_player.p1  = p1;
      Config.disp_player.p2  = p2;
      if (disp) {
      /* child */
      player_stat[p1].disp = SPM_MAPPED;
      player_stat[p2].disp = SPM_MAPPED;
      Config.com_mode = CM_Child;
      set_event_communication(CM_Child, RM_NONE, p1, p2);
      set_setup_communication(CM_Child);
      Config.display[0]=Config.display[disp];
      Config.default_disp = -1;
      Config.record_mode = FALSE;
      goto LeaveForkedConfig;
      }
    } else {
      /* parent */
      Config.com_mode = CM_Parent;
      set_event_communication(CM_Parent, Config.record_mode, p1, p2);
      set_setup_communication(CM_Parent);
    }
  }
  player_stat[Config.disp_player.p1].disp = SPM_MAPPED;
  player_stat[Config.disp_player.p2].disp = SPM_MAPPED;
  
 LeaveForkedConfig:
  /* only display per process, even for parent */
  Config.num_disp = num_disp = 1;
  return;
}

/*
 * local function eval_config
 */
#ifdef __STDC__
static void 
eval_config (char *prog_name)
#else
static void 
eval_config (prog_name)
     char *prog_name;
#endif
{
  static int cur_demo = -1;

  /* check if we are in demo playback mode */
  if (Config.record_mode == RM_PLAYBACK) {
    /* load demo file */
    do {
      cur_demo ++;
      if (NULL == Config.playback[cur_demo]) {
      cur_demo = 0;
      }
    } while (load_demo (Config.playback[cur_demo]));
    config_from_demo(&Config);
  }

  /* set values derived from setup */
  num_player = Config.num_player;
  if (num_player <= 0) {
    bm_fatal("Number of players not defined",prog_name);
  }
  
  /* check number of players */

  num_disp = Config.num_disp;
  if (num_disp <= 0) {
    bm_fatal("Number of displays not defined",prog_name);
  }

  /* set game mode flag */
  switch (num_player) {
  case 2:
    game_mode = GM_2_Player;
    break;
  case 3:
    game_mode = GM_3_Player;
    break;
  case 4:
    game_mode = GM_4_Player;
    break;
  case 5:
    game_mode = GM_5_Player;
    break;
  case 6:
    game_mode = GM_6_Player;
    break;
  default:
    bm_fatal("Unsupported number of players", prog_name);
    break;
  }
  
#ifndef DEBUG
  if ( (num_disp != num_player) && (Config.record_mode != RM_PLAYBACK) ) {
    game_mode |= GM_LR_Players;
  }
#endif

  /* check number of players */
  switch (Config.team_mode) {
  case TM_Single:
    game_mode |= GM_Single;
    break;

  case TM_Team:
    if (! (game_mode & (GM_6_Player|GM_4_Player) ) ) {
      bm_fatal("Team mode only works with 4 or 6 players",prog_name);
    }
    game_mode |= GM_Team;
    break;

  case TM_Double:
    if (! (game_mode & (GM_234_Player) ) ) {
      bm_fatal("Double mode only works with 2, 3 or 4 teams",prog_name);
    }
    game_mode |= GM_Double;
    break;
  }


  /* configure the game */
  config_forked_game();

  /* reset num_player for double mode */
  if (game_mode & GM_Double) {
    num_player *= 2;
    Config.num_player *= 2;
  }

#ifdef DEBUG
  {
    int cdd;

    cdd=Config.default_disp;
    fprintf(stderr, "Default Display is %d: %s\n", cdd, (cdd>=0) ? 
          (Config.display[cdd] ? Config.display[cdd] : "(null)")
          :("none"));
  }
#endif
}



/*
 * local function eval_setup
 */
#ifdef __STDC__
static void 
eval_setup (char *prog_name)
#else
static void 
eval_setup (prog_name)
     char *prog_name;
#endif
{
  int i, n_level;

  FrameTime = Setup.frame_time;
  if (Setup.sound_flag) {
    sound_function = do_bell;
  } else {
    sound_function = no_bell;
  }
  
  /* correct use_level field */
  n_level = 0;
  for (i=0; i<levelMax; i++) {
    if ( game_mode != (game_mode & get_game_mode(i))) {
      /* mode not supported by level */
      if (Setup.use_level[i]) {
      fprintf(stderr, "%s: Level \"%s\" not supported in this game mode.\n",
            prog_name, get_level_name(i) );
      }
      Setup.use_level[i]=FALSE;
    }
    if (Setup.use_level[i]) {
      n_level ++;
    }
  }
  if (n_level == 0) {
    fprintf (stderr, "%s: No Level left to play in this game mode.\n", 
           prog_name);
    exit_prg(1);
  }
  /* set print_stat off for childs */
  if (Config.com_mode == CM_Child) {
    Setup.print_stat = FALSE;
  }
}


#ifdef XBLAST_SOUND
/*
 * local function load_level_sounds
 */
#ifdef __STDC__
static void
load_level_sounds (void)
#else
static void
load_level_sounds ()
#endif
{
  /* load samples which are frequently used 
     now: load all samples (for testing)  */
  load_sound(SND_BAD);
  load_sound(SND_DROP);
  load_sound(SND_NEWBOMB);
  load_sound(SND_NEWKICK);
  load_sound(SND_NEWPUMP);
  load_sound(SND_NEWRC);
  load_sound(SND_MOREFIRE);
  load_sound(SND_DEAD);
  load_sound(SND_EXPL);
  load_sound(SND_KICK);
  load_sound(SND_PUMP);
  load_sound(SND_OUCH);
  load_sound(SND_BUTT);
  load_sound(SND_SHOOT);
  load_sound(SND_INVIS);
  load_sound(SND_INVINC);
  load_sound(SND_NEWTELE);
  load_sound(SND_TELE);
  load_sound(SND_INJ);
  load_sound(SND_MINIBOMB);
  load_sound(SND_HAUNT);
  load_sound(SND_SPIRAL);
  load_sound(SND_SPBOMB);
  load_sound(SND_SLIDE);
  load_sound(SND_STUN);
  load_sound(SND_WARN);
  load_sound(SND_COMPOUND);
  load_sound(SND_TELE1);
  load_sound(SND_TELE2);
  load_sound(SND_HOLY);
  load_sound(SND_ENCLOAK);
  load_sound(SND_DECLOAK);
  load_sound(SND_FAST);
  load_sound(SND_SLOW);
  load_sound(SND_SLAY);
  load_sound(SND_LIFE);
  load_sound(SND_NEWCLOAK);
  load_sound(SND_BOMBMORPH);
  /* these sample are moved up from the level end (ov) */
  load_sound(SND_APPL);
  load_sound(SND_WON);
}
#endif



/* main program what else */
#ifdef __STDC__
int 
main (int argc,
      char *argv[])
#else
int 
main (argc, argv)
     int argc;
     char *argv[];
#endif
{
  int player;
  int level_index;
  LevelField *level_field;
  int setup_flag;
  char win_title[1024];
  int demo_restart = FALSE;
#ifdef DEBUG
  int ft_count;
  double ft_time;
  struct timeval ft_start_time, ft_end_time;
  struct timezone ft_tz;
#endif

  printf("%s\n",c_string);
  printf("Report any bugs to: m.vogel@ndh.net\n");

  /* Initialize Random */
  seed_random((unsigned)getpid());

  /* load levels now */
  load_all_levels();

  /* choose setup method */
  if (1 != argc) {
    parse_commandline(argc, argv);
    setup_flag = FALSE;
  } else {
    setup_flag = ! interactive_config(argv[0]);
  }

#ifdef DEBUG
  /* debug modes from database */
  debug_from_database(&Debug);
#endif
    
  /* get config from database */
  config_from_database(&Config);

  /* demo playback loop */
  do {
    /* evaluate config */
    eval_config(argv[0]);
    
    if (!demo_restart) {
#ifdef XBLAST_SOUND
      /* Initialize sound server */
      if (Config.com_mode != CM_Child) {
      (void) init_sound(sound_server_from_database());
      }
#endif
      /* Initialize Displays and X Databases */
      init_display(Config.display[0]);
      /* merge databases  */
      merge_default_databases(&Config);
      /* alloc use level field */
      if (NULL == (Setup.use_level = (char *) malloc(levelMax*sizeof(char))) ) {
      fprintf(stderr, "Failed to alloc use level array\n");
      exit_prg(1);
      }
    
      /* run interactive setup if necessary */
      if (setup_flag) {
      switch(Config.com_mode) {
      case CM_None:
        interactive_setup(num_player);
        break;
        
      case CM_Parent:
        /* run interactive setup and send data to child processes */
        interactive_setup(num_player);
        send_setup(num_player);
        break;
        
      case CM_Child:
        receive_setup(num_player);
        break;
      }
      }
      /* get setup from internal database*/
      setup_from_database(&Setup);
    }
    
    /* when in playback mode, override with demo setttings */
    if (Config.record_mode == RM_PLAYBACK) {
      setup_from_demo (&Setup);
    }
    
    /* evaluate setup */
    eval_setup(argv[0]);
    
    /* init_players */
    init_players(&Config, &Setup, game_mode);
    
    /* now save setup if needed */
    if (RM_PLAYBACK != Config.record_mode) {
      save_setup(&Config, &Setup, p_string);
      /* load status board and end screen */
      load_score_board(game_mode, Setup.max_victories);
    }
    
    /* Initialize Graphics */
    if (!demo_restart) {
      if (Config.record_mode == RM_PLAYBACK) {
      sprintf(win_title, win_string1, "Demo Playback");
      } else if (Config.disp_player.num == 1) {
      sprintf(win_title, win_string1, p_string[Config.disp_player.p1].tag);
      } else {
      sprintf(win_title, win_string2, p_string[Config.disp_player.p1].tag,
            p_string[Config.disp_player.p2].tag);
      }
      init_graphics(&Config, win_title, icon_string);

      /* now erase al databases */
      delete_databases();
    }

    /* setup status_bar */
    init_status_bar(&Config, player_stat, get_level_name(level), FALSE);

#ifndef DEBUG
    /* Title Screen */
    if (RM_PLAYBACK != Config.record_mode) {
      do_intro(player_stat, p_string, &Config);
    }
#else
    /* Title Screen */
    if ( (! Debug.no_title) && (RM_PLAYBACK != Config.record_mode) ) {
      do_intro(player_stat, p_string, &Config);
    }
#endif
    
    /* the game */
    if (NULL == (level_field = malloc(levelMax*sizeof(LevelField))) ) {
      fprintf(stderr, "Failed to alloc level field\n");
      exit_prg(1);
    }
    for (level_index = 0; level_index < levelMax; level_index ++) {
      level_field[level_index].level = level_index;
    }
    
    if (Setup.random_mode) {
      /* randomize levels */
      for (level_index=0; level_index<levelMax; level_index++) {
      level_field[level_index].value = random_number(65535);
      }
      qsort (level_field, levelMax, sizeof(LevelField), cmp_level_field);
#ifdef DEBUG
      /* find start level */
      for (level_index = 0; level_field[level_index].level != 15; 
         level_index++);
#else
      level_index = 0;
#endif
    } else {
      level_index = Setup.start_level;
    }
    
    
#ifdef XBLAST_SOUND
    if (!demo_restart) {
      load_level_sounds();
    }
#endif
    
    /* games loop (until one player has enough victories) */
    do {
      /* level selection loop */
      do {
      level = level_field[level_index].level;
      
      if ( (++ level_index) >= levelMax ) {
        if (Setup.random_mode) {
          /* randomize levels */
          for (level_index=0; level_index<levelMax; level_index++) {
            level_field[level_index].value = random_number(65535);
          }
          qsort (level_field, levelMax, sizeof(LevelField), cmp_level_field);
        }
        level_index = 0;
      }
      } while (!Setup.use_level[level]);
      
      /* open demo recording file if necessary */
      if (Config.record_mode == RM_RECORD) {
      open_demo (&Config, &Setup, level);
      }
      
      /* reset demo status */
      if (Config.record_mode == RM_PLAYBACK) {
      reset_demo();
      }
      
      /* Set up scrambled start positions */
      if ( (Config.num_player <= 4) || (game_mode & GM_Double)){
      init_shuffle_startpos(4);
      } else {
      init_shuffle_startpos(MAX_PLAYER);
      }
      
      /* load maze from data */
      load_maze(level);
      
      /* Introduce level */
      if (Config.record_mode != RM_PLAYBACK) {
      level_intro(level, player_stat, &Config);
      }
      
      /* setup number of active players or teams */
      switch (Config.team_mode) {
      case TM_Single:
      active_player = num_player;
      break;
      case TM_Team:
      case TM_Double:
      active_player = num_player / 2;
      break;
      }
      
      /* exec special_init_functions */
      (*special_init_function)(player_stat);
      
      /* draw maze in pixmap */
      reset_status_bar(player_stat, get_level_name(level), TRUE);
      draw_maze();
      
      /* mark player positions */
      for (player = 0; player < num_player; player ++) {
      mark_maze_rect (player_stat[player].x + SPRITE_X_OFF, 
                  player_stat[player].y + SPRITE_Y_OFF,
                  SPRITE_WIDTH, SPRITE_HEIGHT);
      }
      
      level_start();
      
      /* set up welcome messages */
      welcome(num_player, p_string);
      
      flush_pixmap(FALSE);
      
      game_time = 0;
      
      init_timer();
      clear_keys(num_player);
      
#ifdef DEBUG
      gettimeofday (&ft_start_time, &ft_tz);
      ft_count = 0;
#endif
      
      do {
#ifdef DEBUG
      ft_count ++;
#endif
      /* kill players if we are near the end of game */
      
      /* check if we are not in PAUSE mode */
      if (pause_status == -1) {
        /* increment game clock */
        game_time ++;

        /* handle players */
        do_all_players(game_time, &active_player);
        
        /* Shrink functions */
        do_shrink(game_time);
        
        /* Scramble blocks */
        do_scramble2(game_time);
        
        /* Game functions */
        (*special_game_function)();
        
        /* check bombs */
        do_bombs();
        
        /* check explosions */
        if(do_explosions()) {
          (*sound_function)();
        }
        
        /* check if bombs are ignited by other bombs */
        ignite_bombs();
        
        /* stun players hit by other bombs */
        stun_players(player_stat, num_player);
        
        /* check if and Virus or Junkie infects another player */
        infect_other_players();
      
        /* do junkie countdown  */
        do_junkie();
        
        /* check if player was hit by any explosions */
        check_player_hit();

        /* update status bar */
        update_status_bar (player_stat, game_time, 
                     (Config.team_mode == TM_Double) );

        /* get events and evaluate them */
        game_event();
        if (game_eval_keys(num_player, player_stat, p_string, 
                       special_key_function, &pause_status)) {
          if (pause_status < 0) {
            do_bell();
            set_message("Continue", TRUE);
          } else {
            set_message(p_string[pause_status].pause, TRUE);
          }
        }
      } else {
        /* increase game time counter, when not in PAUSE mode */
        if (pause_status < 0) {
          pause_status ++;
          if (-1 == pause_status) {
            do_bell();
            reset_message();
          }
        }

        /* update status bar */
        update_status_bar (player_stat, game_time, 
                       (Config.team_mode == TM_Double) );
      
        other_event();
        if (pause_eval_keys(num_player, &pause_status)) {
          if (pause_status < 0) {
            do_bell();
            set_message("Continue", TRUE);
          } else {
            set_message(p_string[pause_status].pause, TRUE);
          }
        }
      }
      
      } while ( (game_time<= GAME_TIME) && 
            ( (active_player > 1) || (number_of_explosions()!=0) ) && 
            (active_player > 0) );
      
      /* close demo file */
      if (Config.record_mode == RM_RECORD) {
      close_demo();
      }
      
#ifdef DEBUG
      gettimeofday (&ft_end_time, &ft_tz);
      ft_time = (double)(ft_end_time.tv_sec - ft_start_time.tv_sec) 
      + (double)(ft_end_time.tv_usec - ft_start_time.tv_usec) / 1E6;
      fprintf(stderr, "Frame rate: %6.3f fps \"%s\"\n",
            ft_count / ft_time, get_level_name(level));
#endif
      
#ifdef XBLAST_SOUND
      if (RM_PLAYBACK != Config.record_mode) {
      play_sound(SND_WON, SOUND_MIDDLE_POSITION);
      }
#endif
      
      level_end();
      unload_blocks();
      delete_all_explosions();
      
#ifndef DEBUG
      if (RM_PLAYBACK != Config.record_mode) {
#ifdef XBLAST_SOUND
      play_sound(SND_APPL, SOUND_MIDDLE_POSITION);
#endif
      status_board(last_team, num_victories, Setup.max_victories, player_stat,
                 p_string, &Config);
      unload_blocks();
      }
#else
      if ( (RM_PLAYBACK != Config.record_mode) && (! Debug.no_score) ) {
#ifdef XBLAST_SOUND
      play_sound(SND_APPL, SOUND_MIDDLE_POSITION);
#endif
      status_board(last_team, num_victories, Setup.max_victories, player_stat, 
                 p_string, &Config);
      unload_blocks();
      }
#endif
    } while ( (Config.record_mode != RM_PLAYBACK) && 
            (num_victories < Setup.max_victories) );

    
#ifdef DEBUG
    fprintf(stderr, "Game finished\n [%d/%d]\n", num_victories, 
          Setup.max_victories);
#endif
    demo_restart = TRUE;

    if (Config.record_mode == RM_PLAYBACK) {
      delete_player_sprites();
    }

  } while (RM_PLAYBACK == Config.record_mode);

#ifdef XBLAST_SOUND
  stop_sound(STOP_ALL_SOUNDS);
  load_sound(SND_FINALE);
  play_sound(SND_FINALE, SOUND_MIDDLE_POSITION);
#endif
  if (RM_PLAYBACK != Config.record_mode) {
    winning_the_game(last_team, player_stat, p_string, &Setup, &Config);
  }
#ifdef XBLAST_SOUND
  stop_sound_server();
#endif
  printf("Ready.\n");
  return 0;
}

/*
 * end of file main.c
 */

Generated by  Doxygen 1.6.0   Back to index