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

event.c

/*
 * Program XBLAST V2.5.11 or higher
 * (C) by Oliver Vogel (e-mail: vogel@ikp.uni-koeln.de)
 * Novermber 16th, 1997
 * started August 1993
 *
 * File: event.c
 * event handlig routines
 *
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public Licences as by 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 entertaining,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
 * MERCHANTABILTY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
 * Publis 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: event.c,v 1.2 1999/05/01 18:53:54 xblast Exp $
 * $Log: event.c,v $
 * Revision 1.2  1999/05/01 18:53:54  xblast
 * kill children when pressing ESC
 *
 * Revision 1.1  1998/01/03 14:11:19  xblast
 * Initial revision
 *
 */

#define _EVENT_C

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/keysym.h>

#include "const.h"
#include "include.h"
#include "mytypes.h"
#include "graphics.h"
#include "map.h"
#include "status.h"
#include "main.h"
#include "func.h"
#include "event.h"
#include "pipe.h"
#include "setup.h"
#include "bomb.h"
#include "sprite.h"
#include "demo.h"
#include "player.h"

#if defined(XBLAST_SOUND)
#include "sound.h"
#endif

/*
 * local variables for delay etc 
 */
static int last_delay = 0;
static int SkipTime =0;
static struct timeval tv1,tv2;
static struct timezone tzp;
#ifdef DEBUG
static FILE *delay_file = NULL;
#endif

/*
 * local variables for player_key etc
 */
static PlayerAction player_action[2*MAX_PLAYER];

/*
 * local function pointers for client-server io
 */

#ifdef __STDC__
static void (*keys_to_server)(void);
static void (*keys_to_clients)(void);
static int  (*wait_function)(int _t);
static void (*record_function)(PlayerAction *pa);
void (*quit_function)(void);
#else
static void (*keys_to_server)();
static void (*keys_to_clients)();
static int  (*wait_function)();
static void (*record_function)();
void (*quit_function)();
#endif



/*
 * public function init_delta_time
 */
#ifdef __STDC__
void 
init_timer (void)
#else
void 
init_timer ()
#endif
{
  /* init timer constants */
  last_delay     = 0;
  SkipTime       = -FrameTime/2;
  /* Now including a bugfix for Solaris (send in ianj@melko.co.uk) */
  do {
    gettimeofday(&tv1,&tzp);
  } while( tv1.tv_usec >999999);
}

/*
 * public function get_delta_time
 */
#ifdef __STDC__
static int 
get_timer (void)
#else
static int 
get_timer ()
#endif
{
  int rueck;

  do {
    gettimeofday(&tv2,&tzp);
  } while( tv2.tv_usec > 999999);
  rueck = ( 1000000*(tv2.tv_sec-tv1.tv_sec)+(tv2.tv_usec-tv1.tv_usec));
  tv1 = tv2;

#ifdef DEBUG
  fprintf (delay_file, "\nT: %5d,", rueck/1000);
#endif

  return rueck;
}



/*
 * local  function wait_micsec
 */
#ifdef __STDC__
static int 
wait_usec (int i)
#else
static int 
wait_usec (i)
     int i;
#endif
{
  static struct timeval tv;

  if (i>0) {
    tv.tv_sec = 0;
    tv.tv_usec = i;
    select(0,NULL,NULL,NULL,&tv);
  }

#ifdef DEBUG
  fprintf (delay_file, "W: %5d,", i/1000);
#endif

  return i;
}

/*
 * local function wait_not
 */
#ifdef __STDC__
static int 
wait_not (int i)
#else
static int 
wait_not (i)
     int i;
#endif
{
  return i;
}


/*
 * local quit functions
 */
#ifdef __STDC__
static void 
quit_simple (void)
#else
static void 
quit_simple ()
#endif
{
  fprintf(stderr, "Quit!\n");
  kill_all_children ();
#if defined(XBLAST_SOUND)
  stop_sound_server();
#endif
  exit_prg(-1);
}

#ifdef __STDC__
static void 
quit_none (void)
#else
static void 
quit_none ()
#endif
{
}



#define NUM_KEYS_SINGLE  (9+2)
#define NUM_KEYS_DOUBLE (18+4)

/*
 * public function set_game_keys
 */
#ifdef __STDC__
void
set_game_keys (XBConfig *config)
#else
void
set_game_keys (config)
     XBConfig *config;
#endif
{
  int n_press, n_release;
  static KeyPressDefine keypress[NUM_KEYS_DOUBLE];
  static KeyPressDefine keyrelease[NUM_KEYS_DOUBLE];
  
  if (1 == config->disp_player.num) {
    n_press = keys_from_database (SINGLE_PLAYER, keypress, 
                         &(player_action[config->disp_player.p1]) );
    n_release = release_from_database (SINGLE_PLAYER, keyrelease, 
                               &(player_action[config->disp_player.p1]));
  } else {
    n_press = keys_from_database (RIGHT_PLAYER, keypress,
                         &(player_action[config->disp_player.p1]) );
    n_press += keys_from_database (LEFT_PLAYER, keypress + n_press,
                          &(player_action[config->disp_player.p2]) );
    n_release = release_from_database (RIGHT_PLAYER, keyrelease, 
                               &(player_action[config->disp_player.p1]));
    n_release += release_from_database (LEFT_PLAYER, keyrelease, 
                               &(player_action[config->disp_player.p2]));
  }
#ifdef DEBUG
  fprintf (stderr, "set_game_keys: %d key press and %d key releases\n",
         n_press, n_release);
#endif
  /* create table */
  link_keysyms (n_press, keypress, n_release, keyrelease);
}
             

/*
 * public function set_communication
 */
#ifdef __STDC__
void
set_event_communication (int type, 
                   BMRecordMode record_mode,
                   int p1, 
                   int p2)
#else
void
set_event_communication (type, record_mode, p1, p2)
  int type;
  BMRecordMode record_mode;
  int p1, p2;
#endif
{
  /* set functions for communication mode */
  switch (type) {
  case CM_None:
    keys_to_server  = no_keys_to_server;
    keys_to_clients = no_keys_to_clients;
    wait_function   = wait_usec;
    quit_function   = quit_simple;
    break;

  case CM_Parent:
    keys_to_server   = get_keys_from_children;
    keys_to_clients  = send_keys_to_children;
    wait_function    = wait_usec;
    quit_function    = quit_simple;
    parent_link_keys(-1, player_action, p1, p2);
    break;

  case CM_Child:
    keys_to_server   = send_keys_to_parent;
    keys_to_clients  = get_keys_from_parent;
    wait_function    = wait_not;
    quit_function    = quit_none;
    child_link_keys(player_action, p1, p2);
    break;
  }

  /* set function for demo record/playback mode */
  switch (record_mode) {
  case RM_RECORD:
    record_function = record_keys;
    break;
  case RM_NONE:
    record_function = record_void;
    break;
  case RM_PLAYBACK:
    record_function = playback_keys;
    break;
  }

#ifdef DEBUG
    if (NULL == delay_file) {
      char name[32];
      sprintf (name, "delay_%05d.txt", getpid ());
      delay_file = fopen (name, "w");
    } else if (type == CM_Child) {
      char name[32];
      fclose (delay_file);
      sprintf (name, "delay_%05d.txt", getpid ());
      delay_file = fopen (name, "w");
    }
    fprintf (delay_file, "Init\n");
#endif
}

/* 
 * local function get_all_keys
 */ 
#ifdef __STDC__
static void 
get_all_keys (void) 
#else
static void 
get_all_keys ()
#endif
{
  check_event();
  (*keys_to_server)();
  (*keys_to_clients)();
}

/* 
 * local function get_all_keys
 */ 
#ifdef __STDC__
static void 
get_all_keys_recorded (void) 
#else
static void 
get_all_keys_recorded ()
#endif
{
  check_event();
  (*keys_to_server)();
  (*record_function)(player_action);
  (*keys_to_clients)();
}

/*
 * public function game_event 
 */
#ifdef __STDC__
void
game_event (void) 
#else
void
game_event ()
#endif
{
#ifdef DEBUG
  static struct timeval t1, t2;
#endif

  /* get last delay be skipped */
  last_delay=(*wait_function)(FrameTime - get_timer() + last_delay);
#ifdef DEBUG
  do {
    gettimeofday(&t1, NULL);
  } while( t1.tv_usec >999999);
#endif
  /* shuffle sprites and mark them */
  shuffle_all_sprites();
  /* set rectangles to be redrawn */
  set_redraw_rectangles();
  /* shuffle sprites and mark them */
  mark_all_sprites();
  /* update maze pixmap */
  update_maze();
  /* draw sprites into pixmap */
  draw_all_sprites();
  /* copy pixmap to window */
  flush_pixmap(1);
#ifdef DEBUG
  do {
    gettimeofday(&t2, NULL);
  } while( t2.tv_usec >999999);
  fprintf (delay_file, "X: %5ld,", 1000*(t2.tv_sec-t1.tv_sec) + (t2.tv_usec - t1.tv_usec)/1000 );
#endif
  /* check all events for all players */
  get_all_keys_recorded();
#ifdef DEBUG
  do {
    gettimeofday(&t1, NULL);
  } while( t1.tv_usec >999999);
  fprintf (delay_file, "P: %5ld,", 1000*(t1.tv_sec-t2.tv_sec) + (t1.tv_usec - t2.tv_usec)/1000 );
#endif
  /* clear redraw rectangles */
  clear_redraw_map();

  if (last_delay < SkipTime) {
    last_delay = 0;
  }
}  

/*
 * public function game_event 
 */
#ifdef __STDC__
void
other_event (void) 
#else
void
other_event ()
#endif
{
  /* get last delay be skipped */
  last_delay=(*wait_function)(FrameTime - get_timer() + last_delay);
  /* shuffle sprites and mark them */
  shuffle_all_sprites();
  /* set rectangles to be redrawn */
  set_redraw_rectangles();
  /* shuffle sprites and mark them */
  mark_all_sprites();
  /* update maze pixmap */
  update_maze();
  /* draw sprites into pixmap */
  draw_all_sprites();
  /* copy pixmap to window */
  flush_pixmap(1);
  /* check all events for all players */
  get_all_keys();
  /* clear redraw rectangles */
  clear_redraw_map();

  if ( (last_delay < SkipTime) ) {
    last_delay = SkipTime;
  }
}  


/*
 * public function intro_event 
 */
#ifdef __STDC__
void
intro_event (void)
#else
void
intro_event ()
#endif
{
  /* delay to get correct frame rate */
  last_delay=(*wait_function)(FrameTime - get_timer() + last_delay);
  /* shuffle sprites and mark them */
  shuffle_all_sprites();
  /* set rectangles to redrawn */
  set_redraw_rectangles();
  /* redraw all blocks */
  flush_blocks();
  /* shuffle sprites and mark them */
  mark_all_sprites();
  /* draw all sprites */
  draw_all_sprites();
  /* update explosions animations */
  update_expl();
  /* update pixmap */
  flush_pixmap(1);
  /* check all events for all players */
  get_all_keys();
  /* clear the redraw map */
  clear_redraw_map();
}  


/*
 * public function clear_keys
 */
#ifdef __STDC__
void
clear_keys (int num_player) 
#else
void
clear_keys (num_player) 
     int num_player;
#endif
{
  int player;

  for (player=0; player<num_player; player++) {
    player_action[player].player  = player;
    player_action[player].dir     = GoDefault;
    player_action[player].bomb    = FALSE;
    player_action[player].special = FALSE;
    player_action[player].pause   = FALSE;
    player_action[player].abort   = ABORT_NONE;
  }
}



/*
 * public function game_eval_keys
 */
#ifdef __STDC__
int
game_eval_keys (int num_player, 
            BMPlayer *player_stat,
            PlayerStrings *p_string,
            PFV key_func,
            int *pause_mode) 
#else
int
game_eval_keys (num_player, player_stat, p_string, key_func, pause_mode) 
     int num_player;
     BMPlayer *player_stat;
     PlayerStrings *p_string;
     PFV key_func;
     int *pause_mode;
#endif
{
  int player;
  BMPlayer *ps;
  PlayerAction *pa;
  int result = FALSE;
  int do_abort;

  for (player=0; player<num_player; player++) {
    ps = player_stat + player;
    pa = player_action + player;

    /* toggle pause mode */
    if ( (ps->lives) && (pa->pause) ) {
      if (*pause_mode == player) {
      /* pause mode off */
      *pause_mode = -PAUSE_DELAY;
      } else if (*pause_mode < 0) {
      /* pause_mode on */
      *pause_mode = player;
      }
      result = TRUE;
    }

    /* drop bomb if needed */
    if (pa->bomb) {
      drop_bomb(ps, BMTdefault);
    }
    /* execute special key function */
    if (pa->special) {
      (*key_func)(ps);
    }
    /* try to abort game if needed */
    if (pa->abort == ABORT_CANCEL) {
      if ((ps->lives >0) && (ps->abort)) {
      set_message (p_string[player].abortcancel, FALSE);
      }
      ps->abort=FALSE;
    }
    if (pa->abort == ABORT_TRUE) {
      if (ps->lives>0) {
      ps->abort = TRUE;
      set_message (p_string[player].abort, FALSE);
      do_abort = TRUE;
      for (player=0;player<num_player;player++) {
        if (player_stat[player].lives >0) {
          do_abort &= player_stat[player].abort;
        }
      }
      if (do_abort) {
        /* Only if everyone agrees */

        set_message("* * Level Aborted * *", TRUE);
        for (player=0;player<num_player;player++) {
          if (player_stat[player].lives > 0) {
            player_stat[player].lives = 1;
            player_stat[player].dying = DEAD_TIME;
          }
        }
      }
      }
    }

    /* get direction */
    if (pa->dir != GoDefault) {
      /* reverse direction  if player is ill */
      if (ps->illness == IllReverse) {
      switch (pa->dir) {
      case GoUp:
        pa->dir = GoDown;
        break;
      case GoDown:
        pa->dir = GoUp;
        break;
      case GoLeft:
        pa->dir = GoRight;
        break;
      case GoRight:
        pa->dir = GoLeft;
        break;
      }
      }
      /* set new course */
      ps->d_soll = pa->dir;
      /* look if player reverts course */
      switch (ps->d_ist) {
      case GoUp:
      if ( ( ( (GoRight == ps->d_soll) || (GoLeft == ps->d_soll) ) &&
            (ps->y % BLOCK_HEIGHT >= (BLOCK_HEIGHT-ps->turn_y) ) ) ||
          ( GoDown == ps->d_soll ) ) {
        ps->d_ist = GoDown;
      }
      break;      
      case GoDown:
      if ( ( ( (GoRight == ps->d_soll) || (GoLeft == ps->d_soll) ) &&
            (ps->y % BLOCK_HEIGHT <= ps->turn_y ) ) ||
          ( GoUp == ps->d_soll ) ) {
        ps->d_ist = GoUp;
      }
      break;      
      case GoRight:
      if ( ( ( (GoUp == ps->d_soll) || (GoDown == ps->d_soll) ) &&
            (ps->x % BLOCK_WIDTH <= ps->turn_x ) ) ||
          ( GoLeft == ps->d_soll ) ) {
        ps->d_ist = GoLeft;
      }
      break;      
      case GoLeft:
      if ( ( ( (GoUp == ps->d_soll) || (GoDown == ps->d_soll) ) &&
            (ps->x % BLOCK_WIDTH >= (BLOCK_WIDTH-ps->turn_x) ) ) ||
          ( GoRight == ps->d_soll ) ) {
        ps->d_ist = GoRight;
      }
      break;      
      default:
      break;
      }
    }
    
    /* clear action struct */
    pa->dir     = GoDefault;
    pa->bomb    = FALSE;
    pa->special = FALSE;
    pa->pause   = FALSE;
    pa->abort   = ABORT_NONE;
  }

  return result;
}


/*
 * public function game_eval_keys
 */
#ifdef __STDC__
int
pause_eval_keys (int num_player, 
             int *pause_mode) 
#else
int
pause_eval_keys (num_player, pause_mode) 
     int num_player;
     int *pause_mode;
#endif
{
  int player;
  PlayerAction *pa;
  int result = FALSE;

  for (player=0; player<num_player; player++) {
    pa = player_action + player;

    /* toggle pause mode */
    if (pa->pause) {
      if (*pause_mode == player) {
      /* pause mode off */
      *pause_mode = -PAUSE_DELAY;
      } else if (*pause_mode < 0) {
      /* pause_mode on */
      *pause_mode = player;
      }
      result = TRUE;
    }
    /* clear action struct */
    pa->dir     = GoDefault;
    pa->bomb    = FALSE;
    pa->special = FALSE;
    pa->pause   = FALSE;
    pa->abort   = ABORT_NONE;
  }

  return result;
}


#ifdef __STDC__
int
wait_eval_keys (int num_player)
#else
int
wait_eval_keys (num_player)
     int num_player;
#endif
{
  int player;
  PlayerAction *pa;
  int result = 0;

  for (player=0; player<num_player; player ++) {
    pa = player_action + player;

    /* bit 0 shifted by player number for resulr mask */
    result |= ((pa->bomb) << player);

    /* clear action struct */
    pa->dir     = GoDefault;
    pa->bomb    = FALSE;
    pa->special = FALSE;
    pa->pause   = FALSE;
  }

  return result;
}



/* 
 * public function fade_in 
 */
#ifdef __STDC__
void 
fade_in (void)
#else
void 
fade_in ()
#endif
{
  int count;
  count = FADE_STEP;

  init_timer();
  last_delay = 0;

  while (count > 1) {
    init_fade(count);
    last_delay=(*wait_function)(FrameTime - get_timer() + last_delay);
    fade_in_window();
    get_all_keys();
    count /= 2;
  }
}


/* 
 * public function fade_out
 */
#ifdef __STDC__
void 
fade_out (void)
#else
void 
fade_out ()
#endif
{
  int count;
  count = FADE_STEP;

  init_timer();
  last_delay = 0;

  while (count > 1) {
    init_fade(count);
    last_delay=(*wait_function)(FrameTime - get_timer() + last_delay);
    fade_out_window();
    get_all_keys();
    count /= 2;
  }
}



/* 
 * public function white_out
 */
#ifdef __STDC__
void 
white_out (void)
#else
void 
white_out ()
#endif
{
  int count;
  count = FADE_STEP;

  init_timer();
  last_delay = 0;

  while (count > 0) {
    init_white(count);
    last_delay=(*wait_function)(FrameTime - get_timer() + last_delay);
    fade_out_window();
    get_all_keys();
    count /= 2;
  }
}



/*
 * end of file event.c
 */


Generated by  Doxygen 1.6.0   Back to index