home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (C) 1992, 1993, 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- /***************************************************************************
- *
- * BZ - Multiplayer tank game.
- *
- * $Id: bz.c,v 1.9 1993/11/29 21:46:00 adele Exp $
- *
- * Chris Fouts - Silicon Graphics, Inc.
- * October, 1991
- **************************************************************************/
- #include <stdio.h>
- #include <stdarg.h>
- #include <stdlib.h>
- #include <string.h>
- #include <bstring.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/utsname.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <device.h>
- #include <math.h>
- #include <errno.h>
- #include <netinet/in.h>
- #include <netdb.h>
- #include <arpa/inet.h>
-
- #include <X11/Intrinsic.h>
- #include <X11/StringDefs.h>
- #include <Xm/Xm.h>
- #include <Xm/BulletinB.h>
- #include <X11/Xirisw/GlxMDraw.h>
- #include <X11/cursorfont.h>
- #include <gl/gl.h>
-
- #include "bz.h"
- #include "bzobjs.h"
- #include "multicast.h"
- #if defined( NETDEBUGGER )
- #include "bznetdebug.h"
- #define BZSCREEN_INTERNAL
- #endif /* defined( NETDEBUGGER ) */
- #include "bzscreen.h"
- #include "bzsound.h"
- #include "bzcollide.h"
- #include "bzvalidate.h"
- #include "bzbase.h"
- #include "framerate.h"
- #include "bzsolo.h"
-
- long gethostid( void ) ;
-
- /* BEGIN PROTOTYPES -S bz.c */
- static void basic_initialization( int *argc, char **argv ) ;
- static void changeTank( Widget w, XEvent *event, String *params,
- Cardinal *numParams ) ;
- static void changeVolume( Widget w, XEvent *event, String *params,
- Cardinal *numParams ) ;
- static void choose_tank( int selection ) ;
- static void composeMail( Widget w, XEvent *event, String *params,
- Cardinal *numParams ) ;
- static void coPilot( Widget w, XEvent *event, String *params,
- Cardinal *numParams ) ;
- static void detonateMine( Widget w, XEvent *event, String *params,
- Cardinal *numParams ) ;
- static void do_a_time_step( void ) ;
- static void drawSceneCB( Widget w, XtPointer client_data,
- XtPointer call_data ) ;
- static void dropFlag( Widget w, XEvent *event, String *params,
- Cardinal *numParams ) ;
- static void drop_mine( int permanent ) ;
- static void dropMine( Widget w, XEvent *event, String *params,
- Cardinal *numParams ) ;
- static void dropPermanentMine( Widget w, XEvent *event, String *params,
- Cardinal *numParams ) ;
- static void fireGuidedShot( Widget w, XEvent *event, String *params,
- Cardinal *numParams ) ;
- static void fireNormalShot( Widget w, XEvent *event, String *params,
- Cardinal *numParams ) ;
- static int getview( float x, float y, float heading, unsigned i,
- int *view, float xref, float yref, float cull_head ) ;
- static void grabFlag( Widget w, XEvent *event, String *params,
- Cardinal *numParams ) ;
- static void identifyTank( Widget w, XEvent *event, String *params,
- Cardinal *numParams ) ;
- static void initGlCB( Widget w, XtPointer client_data,
- XtPointer call_data ) ;
- static void input_message( int init ) ;
- static void installColormapWithOverlay( void ) ;
- static void join_a_team( int team ) ;
- static void joinBlueTeam( Widget w, XEvent *event, String *params,
- Cardinal *numParams ) ;
- static void joinRedTeam( Widget w, XEvent *event, String *params,
- Cardinal *numParams ) ;
- static void mouse_interpret( int mouse_x, int mouse_y ) ;
- static void mouseTrack( Widget w, XEvent *event, String *params,
- Cardinal *numParams ) ;
- static void move_args( int argc, char **argv, int start, int n ) ;
- static void nextCoPilot( Widget w, XEvent *event, String *params,
- Cardinal *numParams ) ;
- static void next_copilot_view( void ) ;
- static void overlayExposeCB( Widget w, XtPointer client_data,
- XtPointer call_data ) ;
- static void parse_args( int *argc, char **argv ) ;
- static void pickUpMine( Widget w, XEvent *event, String *params,
- Cardinal *numParams ) ;
- static void player_dropped_flag( struct BzMember *fumbler ) ;
- static void print_help( float sx, float sy, int prompt ) ;
- static void process_bz_notice( struct BzNotice *input, int team ) ;
- static void quit( Widget w, XEvent *event, String *params,
- Cardinal *numParams ) ;
- static Boolean randomizerWP( XtPointer ignore ) ;
- static void reinterpret_mouse( void ) ;
- static void resetGun( Widget w, XEvent *event, String *params,
- Cardinal *numParams ) ;
- static void reset_mouse( void ) ;
- static void selfDestruct( Widget w, XEvent *event, String *params,
- Cardinal *numParams ) ;
- static void sendPresetMail( Widget w, XEvent *event, String *params,
- Cardinal *numParams ) ;
- static void sendPresetTeamMail( Widget w, XEvent *event, String *params,
- Cardinal *numParams ) ;
- static void setName( void ) ;
- static void setTranslations( XtTranslations transTable ) ;
- static void slowDown( Widget w, XEvent *event, String *params,
- Cardinal *numParams ) ;
- static void stopRandomizing( Widget w, XEvent *event, String *params,
- Cardinal *numParams ) ;
- static void stopWatch( Widget w, XEvent *event, String *params,
- Cardinal *numParams ) ;
- static void tankSelect( Widget w, XEvent *event, String *params,
- Cardinal *numParams ) ;
- static Boolean timeStepWP( XtPointer w ) ;
- static void toggleAudio( Widget w, XEvent *event, String *params,
- Cardinal *numParams ) ;
- static void toggleBinoculars( Widget w, XEvent *event, String *params,
- Cardinal *numParams ) ;
- static void toggleLogos( Widget w, XEvent *event, String *params,
- Cardinal *numParams ) ;
- static void togglePause( Widget w, XEvent *event, String *params,
- Cardinal *numParams ) ;
- static void toggleShowHelp( Widget w, XEvent *event, String *params,
- Cardinal *numParams ) ;
- static void toggleShowScore( Widget w, XEvent *event, String *params,
- Cardinal *numParams ) ;
- static void toggleShowTimings( Widget w, XEvent *event, String *params,
- Cardinal *numParams ) ;
- static void tran_rot_show( float x, float y, float heading,
- GL_Object obj ) ;
- static void try_to_grab_flag( int flag_n ) ;
- static int underStaffedTeam( void ) ;
- static void usage( void ) ;
- static void writeMail( Widget w, XEvent *event, String *params,
- Cardinal *numParams ) ;
- static void writeTeamMail( Widget w, XEvent *event, String *params,
- Cardinal *numParams ) ;
- static void zoomIn( Widget w, XEvent *event, String *params,
- Cardinal *numParams ) ;
- static void zoomOut( Widget w, XEvent *event, String *params,
- Cardinal *numParams ) ;
- /* END PROTOTYPES -S bz.c */
-
- static char *version_id = "$Id: bz.c,v 1.9 1993/11/29 21:46:00 adele Exp $" ;
-
- /*
- * Various variables for I/O.
- */
- static int in_fd = -1 ;
- static int out_fd = -1 ;
- static char *in_name = NULL ;
- static char *out_name = NULL ;
- static int in_addrlen ;
- static int out_addrlen ;
- static struct sockaddr_in in_addr, out_addr ;
- static Boolean networking = TRUE ;
- Packet_Function read_packets ;
- Packet_Function write_packets ;
- Boolean solo = FALSE ;
- Boolean kids_mode = FALSE ;
-
-
- /*
- * Screen position variables.
- */
- DECLARE( MVIEW ) ;
- DECLARE( RADAR ) ;
- DECLARE( HEAD ) ;
- DECLARE( LOADM ) ;
- DECLARE( READY ) ;
- DECLARE( SCORE ) ;
- DECLARE( LIVES ) ;
- DECLARE( LEVEL ) ;
- DECLARE( NOPLY ) ;
- DECLARE( RIGHT ) ;
- DECLARE( LEFTT ) ;
- DECLARE( LOGOD ) ;
- DECLARE( MESGS ) ;
- DECLARE( OUTMS ) ;
- DECLARE( GROND ) ;
- DECLARE( MINES ) ;
- DECLARE( FLAGS ) ;
- float char_width ;
- float char_height ;
- float mv_w ;
- float mv_h ;
- float mv_m ;
- static float aspect_ratio = 1.f ;
- long screen_w, screen_h ;
-
-
- /*
- * Mail and messages.
- */
- struct BzNotice mail ;
- unsigned int sending_msg = SENDING_NO_MAIL ;
- char mail_buffer[MAIL_MSG_SIZE] ;
- int mail_ptr = 0 ;
-
- static int zoom_level = 2 ;
- static float zoom_settings[] = { 1., 1.5, 2., 3., 4., 6., 8. } ;
- float zoom_factor = 2. ;
-
-
-
- /*
- * Various timings.
- */
- #define MAX_HIT_COUNT 5 /* half a second */
- #define MAX_HIT_BY_COUNT ( MAX_DEAD_STATUS - 5 )
-
- /*
- * Values for the screen fracturing effect.
- */
- struct lineset fracture[30] ;
- int fracdest[120] =
- { 300, 0,400,100, 400,100,500,150, 1023,300,875,225, 500,150,475,200,
- 875,225,800, 75, 400,100,200,225, 200,225,450,300, 800, 75,850, 25,
- 800, 75,700, 50, 450,300,250,375, 838,150,775,175, 875,225,750,275,
- 340,340,450,450, 400,400,650,425, 750,275,550, 50, 525,412,550,500,
- 660,175,575,300, 575,300,450,250, 200,225,200,350, 575,300,575,360,
- 200,300, 75,375, 575,350,500,380, 750,275,650,350, 300, 0,175,125,
- 175,125,150,200, 683,325,775,400, 1023,300,950,375, 175,125,125,100,
- 200,100,300,125, 950,375,875,350
- } ;
-
- /*
- * Identity matrix.
- */
- Matrix id_mat = {
- { 1.0, 0.0, 0.0, 0.0 },
- { 0.0, 1.0, 0.0, 0.0 },
- { 0.0, 0.0, 1.0, 0.0 },
- { 0.0, 0.0, 0.0, 1.0 },
- } ;
-
- /*
- * Team related globals.
- */
- static long teamBonus[N_TEAMS] = { 0, 0, 0 } ;
- static char time_name[40] ;
- static char *teamName[] = { "Neutral", "Red", "Blue" } ;
- static Boolean pick_my_team = FALSE ;
- Colorindex teamColor[N_TEAMS] ;
-
- /*
- * Tank velocities.
- */
- float vmax[] = { 28., 35., 28., 42. } ;
- float top_speed = 1.0 ;
- float left_track = 0. ;
- float right_track = 0. ;
- float t_factor ; /* turn factor */
- static float left_track_engaged = 0 ;
- static float right_track_engaged = 0 ;
- int tank_body[] = { 0, 1, 0, 2 } ;
- float gm_vel = GM_VEL ;
- float rm_vel = RM_VEL ;
-
- #define FAST_FACTOR 6.0f
-
- #define PERSONAL_BONUS 200
-
-
-
- /*
- * Administrative variables.
- */
- char *basename ;
- long over_mode = OVERDRAW ;
- int init_wait = 1 ;
- Boolean picking_tank ;
- char player_name[NAMELEN];
- unsigned short game_key = 0 ;
- static int map_counter = 0 ;
- static Window map_window[3] ;
- static int map_index[3] ;
- static unsigned name_count = 0 ;
- extern int msg_redraw ;
- extern int msg_count ;
- extern float radar_view_angle[3][2] ;
- extern float binocular_radar_view_angle[3][2] ;
-
- /*
- * Logo support.
- */
- struct BzLogo logo_packet ;
- static char *logo_file = NULL ;
- static int announce_logo = 1 ;
-
- /*
- * Graphics objects.
- */
- GL_Object tank[N_TEAMS][N_TYPES][N_VIEWS];
- GL_Object cube[N_VIEWS];
- GL_Object pyrm[N_VIEWS];
- GL_Object missile[N_VIEWS];
- GL_Object flag[N_FLAGS][N_VIEWS];
- GL_Object null_obj = 0 ;
- GL_Object crosshairs ;
- GL_Object ground ;
- GL_Object sky ;
- GL_Object man_part ;
- GL_Object border ;
- GL_Object mv_black_clear ;
- GL_Object mv_guided_bg ;
- GL_Object mv_normal_bg ;
- GL_Object mv_set_yellow ;
- GL_Object mv_set_red ;
- GL_Object mv_set_white ;
- GL_Object lights_on ;
- GL_Object lights_off ;
- GL_Object msl_expl[MEXPL_DURATION] ;
- GL_Object explosion[N_TEAMS][EXPDURATION][N_TYPES] ;
- GL_Object digit[10][2] ;
- GL_Object flag_homes ;
- GL_Object flag_homes_mv ;
- GL_Object tank_logo[MAXPLAYERS] ;
- int tank_logo_side[MAXPLAYERS] ;
-
- /*
- * Color values.
- */
- Colorindex black ;
- Colorindex red ;
- Colorindex green ;
- Colorindex yellow ;
- Colorindex white ;
- Colorindex blue ;
-
- /*
- * Positions, headings, and velocities of selected objects.
- */
- float obst_x[TOTALOBSTS] ; /* positions of all objects */
- float obst_y[TOTALOBSTS] ;
- float flag_x[N_FLAGS] ; /* positions of all flags */
- float flag_y[N_FLAGS] ;
- float mine_x ;
- float mine_y ;
- float last_msl_x[MAX_ENEMY+1] ;
- float last_msl_y[MAX_ENEMY+1] ;
- float vx[MAX_ENEMY+1] ; /* velocities of tanks (self and robots) */
- float vy[MAX_ENEMY+1] ;
- float msl_vx[MAX_ENEMY+1] ; /* velocities of missiles */
- float msl_vy[MAX_ENEMY+1] ;
- float head[TOTALOBSTS] ; /* headings of objects */
-
- /*
- * Sorted view stuff.
- */
- float dst[TOTALOBJS] ; /* distance from viewer of all obs*/
- unsigned view_order[TOTALOBJS] ; /* viewing order */
- GL_Object view_object[TOTALOBJS] ;/* view object */
- int n_view_objs = 0 ;
- static Boolean show_copilot_view = FALSE ;
- static unsigned int copilot_player = 1 ;
-
- /*
- * Missile stuff.
- */
- Boolean guiding = FALSE ;
- static Boolean guided_missile = FALSE ;
- long loading_missile = 0 ;
- int missile_duration = 0 ;
- Boolean ricochet = FALSE ;
-
- /*
- * Graphics support.
- */
- int screen_mode ;
- int ol_mode = -1 ;
- Boolean use_pups = FALSE ;
- Boolean db_base ;
- Boolean mv_RGB ;
- Boolean use_textures ;
-
- unsigned int lives ;
- unsigned int level ;
- unsigned int practice_level = 0 ;
- unsigned int number_players ;
- int mine_status ;
- int perm_mine = 0 ;
- unsigned int mine_left = 1 ;
- int hit_count ;
- Boolean binoculars = FALSE ;
- Boolean show_logos = TRUE ;
- Boolean randomizer ;
- Boolean showMan ;
- Boolean transparentExplosion ;
- Boolean view_only = FALSE ;
- static float min_cull_angle ;
- static float max_cull_angle ;
- static int no_sfx ;
- static int timeToLive = 0 ;
- static short new_tank_type = 0 ;
-
- /*
- * Miscellaneous time things.
- */
- float d_time = 1.0f ;
- struct timeval last_time ;
- struct timeval missile_launch_time ;
- struct timeval missile_explode_time ;
- struct timeval time_of_death ;
- struct timeval hit_time ;
- struct timeval current_time ;
- struct timeval start_up_time ;
- struct timeval deadline[MAXPLAYERS] ;
- Boolean paused = FALSE ;
-
- struct BzMember player[MAXPLAYERS] ;
- int hit_by[MAXPLAYERS] ;
- int activity[MAXPLAYERS] ;
-
- /*
- * Flag stuff.
- */
- Boolean never_have_flag = FALSE ;
- Boolean show_flags = FALSE ;
- Boolean red_team_present = FALSE ;
- Boolean blue_team_present = FALSE ;
- Boolean red_flag_held = FALSE ;
- Boolean blue_flag_held = FALSE ;
-
- /*
- * Interaction indicators.
- */
- static Boolean need_to_set_tank = FALSE ;
- static Boolean need_to_show_zoom = FALSE ;
- static Boolean need_to_show_out_message = FALSE ;
- static Boolean need_to_show_mine_st = FALSE ;
- static Boolean need_to_show_flag_st = FALSE ;
- Boolean need_to_show_lives = FALSE ;
- Boolean need_to_show_score = FALSE ;
- Boolean need_to_show_msgs = FALSE ;
- Boolean need_to_show_level = FALSE ;
- Boolean need_to_show_players = FALSE ;
- int need_to_show_msgs_vocal = 0 ;
- static Boolean want_to_slow_down = FALSE ;
- static Boolean want_to_see_timings = FALSE ;
- static Boolean want_to_see_score = FALSE ;
- static Boolean want_to_see_help = FALSE ;
- static Boolean want_to_drop_normal_mine = FALSE ;
- static Boolean want_to_drop_permanent_mine = FALSE ;
- static Boolean want_to_pick_mine = FALSE ;
- static Boolean want_to_detonate_mine = FALSE ;
- static Boolean want_to_identify = FALSE ;
- static Boolean want_to_grab_flag = FALSE ;
- static Boolean want_to_drop_flag = FALSE ;
- static Boolean fire_normal_missile = FALSE ;
- static Boolean fire_guided_missile = FALSE ;
- static Boolean quit_guided_missile = FALSE ;
-
-
- /*
- * X stuff.
- */
- Widget toplevel ;
- Widget base_widget ;
- Widget mainview_widget ;
- Widget radar_widget ;
- Window mainview_window ;
- Window base_window ;
- Window radar_window ;
- Window radar_ol_window ;
- XtAppContext appContext ;
- Arg wargs[20] ;
- Display *display ;
-
-
- /* The GLX configuration parameter:
- * Double buffering
- * RGB mode
- * Z buffering
- * nothing else special
- */
- static GLXconfig baseGlxConfig[] = {
- { GLX_NORMAL, GLX_DOUBLE, FALSE },
- { 0, 0, 0 }
- };
-
- static GLXconfig mainviewGlxConfig[] = {
- { GLX_NORMAL, GLX_DOUBLE, TRUE },
- { GLX_NORMAL, GLX_RGB, FALSE },
- { 0, 0, 0 }
- };
-
- static GLXconfig radarviewGlxConfig[] = {
- { GLX_NORMAL, GLX_DOUBLE, TRUE },
- { GLX_OVERLAY, GLX_BUFSIZE, 2 }, /* Keep in position */
- { 0, 0, 0 }
- };
-
-
-
- static XtActionsRec actionsTable[] = {
- { "quit", quit },
- { "tankSelect", tankSelect },
- { "changeVolume", changeVolume },
- { "stopRandomizing", stopRandomizing },
- { "coPilot", coPilot },
- { "nextCoPilot", nextCoPilot },
- { "zoomIn", zoomIn },
- { "zoomOut", zoomOut },
- { "dropMine", dropMine },
- { "dropPermanentMine", dropPermanentMine },
- { "detonateMine", detonateMine },
- { "grabFlag", grabFlag },
- { "dropFlag", dropFlag },
- { "pickUpMine", pickUpMine },
- { "toggleShowTimings", toggleShowTimings },
- { "toggleShowScore", toggleShowScore },
- { "toggleShowHelp", toggleShowHelp },
- { "identifyTank", identifyTank },
- { "changeTank", changeTank },
- { "writeMail", writeMail },
- { "writeTeamMail", writeTeamMail },
- { "sendPresetMail", sendPresetMail },
- { "sendPresetTeamMail", sendPresetTeamMail },
- { "composeMail", composeMail },
- { "fireNormalShot", fireNormalShot },
- { "fireGuidedShot", fireGuidedShot },
- #if defined(DEBUG)
- { "selfDestruct", selfDestruct },
- { "slowDown", slowDown },
- { "stopWatch", stopWatch },
- { "resetGun", resetGun },
- #endif /* defined(DEBUG) */
- { "toggleAudio", toggleAudio },
- { "toggleBinoculars", toggleBinoculars },
- { "toggleLogos", toggleLogos },
- { "togglePause", togglePause },
- { "mouseTrack", mouseTrack },
- { "joinBlueTeam", joinBlueTeam },
- { "joinRedTeam", joinRedTeam },
- };
-
-
- static char introTranslations[] =
- "<KeyDown>osfCancel: quit() \n"
- "<KeyDown>: stopRandomizing() \n"
- "<BtnDown>: stopRandomizing() \n"
- ;
-
- static char introPickTranslations[] =
- "<KeyDown>osfCancel: quit() \n"
- "<KeyDown>1: tankSelect(1) \n"
- "<KeyDown>2: tankSelect(2) \n"
- "<KeyDown>3: tankSelect(3) \n"
- "<KeyDown>4: tankSelect(4) \n"
- ;
-
- static char *deadTranslations ;
-
- static char soloDeadTranslations[] =
- "<KeyDown>osfCancel: quit() \n"
- "<KeyDown>osfUp: changeVolume(1) \n"
- "<KeyDown>osfDown: changeVolume(0) \n"
- "<KeyDown>a: zoomOut() \n"
- "Shift<KeyDown>p: togglePause() \n"
- "Shift<KeyDown>z: zoomOut() \n"
- "<KeyDown>z: zoomIn() \n"
- ;
-
- static char netDeadTranslations[] =
- "<KeyDown>osfCancel: quit() \n"
- "<KeyDown>osfUp: changeVolume(1) \n"
- "<KeyDown>osfDown: changeVolume(0) \n"
- "<KeyDown>a: zoomOut() \n"
- "<KeyDown>b: joinBlueTeam() \n"
- "<KeyDown>c: changeTank() \n"
- "<KeyDown>m: writeMail() \n"
- "<KeyDown>r: joinRedTeam() \n"
- "<KeyDown>t: writeTeamMail() \n"
- "Shift<KeyDown>z: zoomOut() \n"
- "<KeyDown>z: zoomIn() \n"
- "Shift<KeyDown>1: sendPresetTeamMail(1) \n"
- "Shift<KeyDown>2: sendPresetTeamMail(2) \n"
- "Shift<KeyDown>3: sendPresetTeamMail(3) \n"
- "Shift<KeyDown>4: sendPresetTeamMail(4) \n"
- "Shift<KeyDown>5: sendPresetTeamMail(5) \n"
- "<KeyDown>1: sendPresetMail(1) \n"
- "<KeyDown>2: sendPresetMail(2) \n"
- "<KeyDown>3: sendPresetMail(3) \n"
- "<KeyDown>4: sendPresetMail(4) \n"
- "<KeyDown>5: sendPresetMail(5) \n"
- ;
-
- static char deadMailTranslations[] =
- "<KeyDown>osfCancel: quit() \n"
- "<KeyDown>osfUp: changeVolume(1) \n"
- "<KeyDown>osfDown: changeVolume(0) \n"
- "<KeyDown>: composeMail() \n"
- ;
-
- static char liveMailTranslations[] =
- "<KeyDown>osfCancel: quit() \n"
- "<KeyDown>osfUp: changeVolume(1) \n"
- "<KeyDown>osfDown: changeVolume(0) \n"
- "<Btn1Down>: fireNormalShot() \n"
- "<Btn2Down>: fireGuidedShot() \n"
- "<Motion>: mouseTrack() \n"
- "<Btn3Down>: identifyTank() \n"
- "<KeyDown>: composeMail() \n"
- ;
-
- static char *mainTranslations ;
-
- static char netMainTranslations[] =
- #if defined(DEBUG)
- "<KeyDown>space: slowDown() \n"
- "Ctrl Alt<KeyDown>b: selfDestruct() \n"
- "<KeyDown>w: stopWatch() \n"
- "<KeyDown>r: resetGun() \n"
- #endif /* defined(DEBUG) */
- "<KeyDown>osfUp: changeVolume(1) \n"
- "<KeyDown>osfDown: changeVolume(0) \n"
- "<KeyDown>?: toggleShowTimings() \n"
- "<KeyDown>osfCancel: quit() \n"
- "<Btn1Down>: fireNormalShot() \n"
- "<Btn2Down>: fireGuidedShot() \n"
- "<Motion>: mouseTrack() \n"
- "<Btn3Down>: identifyTank() \n"
- "<KeyDown>a: zoomOut() \n"
- "<KeyDown>b: toggleBinoculars() \n"
- "Shift<KeyDown>d: dropPermanentMine() \n"
- "<KeyDown>c: dropFlag() \n"
- "<KeyDown>d: dropMine() \n"
- "Shift<KeyDown>f: dropFlag() \n"
- "<KeyDown>f: grabFlag() \n"
- "<KeyDown>h: toggleShowHelp() \n"
- "<KeyDown>l: toggleLogos() \n"
- "<KeyDown>m: writeMail() \n"
- "Shift<KeyDown>p: togglePause() \n"
- "<KeyDown>p: pickUpMine() \n"
- "Shift<KeyDown>s: toggleAudio() \n"
- "<KeyDown>s: toggleShowScore() \n"
- "<KeyDown>t: writeTeamMail() \n"
- "<KeyDown>x: detonateMine() \n"
- "Shift<KeyDown>z: zoomOut() \n"
- "<KeyDown>z: zoomIn() \n"
- "Shift<KeyDown>1: sendPresetTeamMail(1) \n"
- "Shift<KeyDown>2: sendPresetTeamMail(2) \n"
- "Shift<KeyDown>3: sendPresetTeamMail(3) \n"
- "Shift<KeyDown>4: sendPresetTeamMail(4) \n"
- "Shift<KeyDown>5: sendPresetTeamMail(5) \n"
- "<KeyDown>1: sendPresetMail(1) \n"
- "<KeyDown>2: sendPresetMail(2) \n"
- "<KeyDown>3: sendPresetMail(3) \n"
- "<KeyDown>4: sendPresetMail(4) \n"
- "<KeyDown>5: sendPresetMail(5) \n"
- ;
-
-
- static char viewonlyTranslations[] =
- #if defined(DEBUG)
- "<KeyDown>space: slowDown() \n"
- "Ctrl Alt<KeyDown>b: selfDestruct() \n"
- "<KeyDown>w: stopWatch() \n"
- #endif /* defined(DEBUG) */
- "<KeyDown>osfUp: changeVolume(1) \n"
- "<KeyDown>osfDown: changeVolume(0) \n"
- "<KeyDown>?: toggleShowTimings() \n"
- "<KeyDown>osfCancel: quit() \n"
- "<Motion>: mouseTrack() \n"
- "<Btn1Down>: identifyTank() \n"
- "<Btn2Down>: identifyTank() \n"
- "<Btn3Down>: identifyTank() \n"
- "<KeyDown>a: zoomOut() \n"
- "<KeyDown>b: toggleBinoculars() \n"
- "<KeyDown>c: coPilot() \n"
- "<KeyDown>l: toggleLogos() \n"
- "Shift<KeyDown>s: toggleAudio() \n"
- "<KeyDown>s: toggleShowScore() \n"
- "<KeyDown>h: toggleShowHelp() \n"
- "<KeyDown>n: nextCoPilot() \n"
- "Shift<KeyDown>z: zoomOut() \n"
- "<KeyDown>z: zoomIn() \n"
- ;
-
-
- static XtTranslations introTransTable ;
- static XtTranslations introPickTransTable ;
- static XtTranslations deadTransTable ;
- static XtTranslations deadMailTransTable ;
- static XtTranslations liveMailTransTable ;
- static XtTranslations mainTransTable ;
-
-
- static String fallbacks[] = {
- "*fontList: -*-helvetica-bold-r-normal--14-*",
- "*cursorForeground: yellow",
- "*cursorBackground: black",
- "*cursor: diamond_cross",
- "*audio: TRUE",
- "*keyboardFocusPolicy: pointer",
- "*mwmDecorations: 0",
- "*geometry: +0+0",
- NULL
- } ;
-
- typedef struct {
- Pixel cursorForeground ;
- Pixel cursorBackground ;
- Cursor cursor ;
- Boolean mvRGBmode ;
- Boolean audio ;
- Boolean showMan ;
- Boolean useTextures ;
- int initialVolume ;
- int ttl ;
- char *identifier ;
- char *logoFile ;
- char *message1 ;
- char *message2 ;
- char *message3 ;
- char *message4 ;
- char *message5 ;
- } AppData, *AppDataPtr ;
-
- AppData AppRes ;
-
- static XtResource resources[] = {
- { "cursorForeground", "CursorForeground", XtRPixel,
- sizeof(Pixel), XtOffset( AppDataPtr, cursorForeground ),
- XtRString, "Red" },
- { "cursorBackground", "CursorBackground", XtRPixel,
- sizeof(Pixel), XtOffset( AppDataPtr, cursorBackground ),
- XtRString, "White" },
- { "cursor", "Cursor", XtRCursor,
- sizeof(Cursor), XtOffset( AppDataPtr, cursor ),
- XtRString, "diamond_cross" },
- { "mvRGBmode", "MvRGBmode", XtRBoolean,
- sizeof(Boolean), XtOffset( AppDataPtr, mvRGBmode ),
- XtRString, "True" },
- { "useTextures", "UseTextures", XtRBoolean,
- sizeof(Boolean), XtOffset( AppDataPtr, useTextures ),
- XtRString, "True" },
- { "audio", "Audio", XtRBoolean,
- sizeof(Boolean), XtOffset( AppDataPtr, audio ),
- XtRString, "True" },
- { "showMan", "ShowMan", XtRBoolean,
- sizeof(Boolean), XtOffset( AppDataPtr, showMan ),
- XtRString, "True" },
- { "volume", "Volume", XtRInt,
- sizeof(int), XtOffset( AppDataPtr, initialVolume ),
- XtRString, "-1" },
- { "ttl", "Ttl", XtRInt,
- sizeof(int), XtOffset( AppDataPtr, ttl ),
- XtRString, "8" },
- { "identifier", "Identifier", XtRString,
- sizeof(char *), XtOffset( AppDataPtr, identifier ),
- XtRString, "" },
- { "logoFile", "LogoFile", XtRString,
- sizeof(char *), XtOffset( AppDataPtr, logoFile ),
- XtRString, "" },
- { "message1", "Message1", XtRString,
- sizeof(char *), XtOffset( AppDataPtr, message1 ),
- XtRString, "" },
- { "message2", "Message2", XtRString,
- sizeof(char *), XtOffset( AppDataPtr, message2 ),
- XtRString, "" },
- { "message3", "Message3", XtRString,
- sizeof(char *), XtOffset( AppDataPtr, message3 ),
- XtRString, "" },
- { "message4", "Message4", XtRString,
- sizeof(char *), XtOffset( AppDataPtr, message4 ),
- XtRString, "" },
- { "message5", "Message5", XtRString,
- sizeof(char *), XtOffset( AppDataPtr, message5 ),
- XtRString, "" },
- } ;
-
-
-
- /*------------------------------------------------------------------------------
- * MAIN routine. Initialize, set up the windows, and fall into X main loop.
- *----------------------------------------------------------------------------*/
- int main(
- int argc,
- char **argv
- )
- {
- int n ;
- Widget bb ;
-
- basic_initialization( &argc, argv ) ;
-
- #if !defined( NETDEBUGGER )
- #if defined( SVR3 )
- toplevel = XtAppInitialize( &appContext, "Bz", NULL, 0,
- (unsigned int *)&argc, argv, fallbacks, NULL, 0 ) ;
- #else
- toplevel = XtAppInitialize( &appContext, "Bz", NULL, 0, &argc, argv,
- fallbacks, NULL, 0 ) ;
- #endif /* SVR3 */
- #endif /* !defined( NETDEBUGGER ) */
-
- if( argc > 1 ) {
- usage() ;
- }
-
- #if !defined( NETDEBUGGER )
- if( !XmIsMotifWMRunning( toplevel ) ) {
- fprintf( stderr, "%s: No supported window manager (mwm or 4Dwm) is ",
- "running. Results are unpredictable.\n", basename ) ;
- }
-
- n = 0 ;
- XtSetArg( wargs[n], XmNmwmDecorations, 0 ) ; n++ ;
- XtSetArg( wargs[n], XmNx, 0 ) ; n++ ;
- XtSetArg( wargs[n], XmNy, 0 ) ; n++ ;
- XtSetArg( wargs[n], XtNborderWidth, 0 ) ; n++ ;
- XtSetValues( toplevel, wargs, n ) ;
- display = XtDisplay( toplevel ) ;
-
- XtGetApplicationResources( toplevel, (XtPointer)&AppRes, resources,
- XtNumber( resources ), NULL, 0 ) ;
-
- if( mv_RGB ) {
- mv_RGB = AppRes.mvRGBmode ;
- }
-
- if( use_textures ) {
- use_textures = AppRes.useTextures ;
- }
-
- if( AppRes.audio == FALSE ) {
- toggle_sound() ;
- }
- else {
- set_volume( AppRes.initialVolume ) ;
- }
-
- showMan = ( kids_mode ) ? FALSE : AppRes.showMan ;
-
- if( timeToLive == 0 ) {
- timeToLive = AppRes.ttl ;
- }
-
- setName() ;
-
- XtAppAddActions( appContext, actionsTable, XtNumber(actionsTable) ) ;
-
- introTransTable = XtParseTranslationTable( introTranslations ) ;
- introPickTransTable = XtParseTranslationTable( introPickTranslations ) ;
- deadTransTable = XtParseTranslationTable( deadTranslations ) ;
- deadMailTransTable = XtParseTranslationTable( deadMailTranslations ) ;
- liveMailTransTable = XtParseTranslationTable( liveMailTranslations ) ;
- mainTransTable = XtParseTranslationTable( mainTranslations ) ;
-
- /* if using pups, modify the config parameter */
- if( use_pups ) {
- radarviewGlxConfig[1].buffer = GLX_POPUP;
- radarviewGlxConfig[1].arg = getgdesc( GD_BITS_PUP_SNG_CMODE ) ;
- }
- else {
- radarviewGlxConfig[1].arg = getgdesc( GD_BITS_OVER_SNG_CMODE ) ;
- }
-
- baseGlxConfig[0].arg = db_base ;
-
- n = 0 ;
- XtSetArg( wargs[n], XmNx, 0 ) ; n++ ;
- XtSetArg( wargs[n], XmNy, 0 ) ; n++ ;
- XtSetArg( wargs[n], XmNwidth, screen_w ) ; n++ ;
- XtSetArg( wargs[n], XmNheight, screen_h ) ; n++ ;
- XtSetArg( wargs[n], XmNmarginHeight, 0 ) ; n++ ;
- XtSetArg( wargs[n], XmNmarginWidth, 0 ) ; n++ ;
- bb = XtCreateManagedWidget( "bboard", xmBulletinBoardWidgetClass,
- toplevel, wargs, n ) ;
-
- n = 0 ;
- XtSetArg( wargs[n], XmNx, 0 ) ; n++ ;
- XtSetArg( wargs[n], XmNy, 0 ) ; n++ ;
- XtSetArg( wargs[n], XmNwidth, screen_w ) ; n++ ;
- XtSetArg( wargs[n], XmNheight, screen_h ) ; n++ ;
- XtSetArg( wargs[n], GlxNglxConfig, baseGlxConfig ) ; n++ ;
- base_widget = XtCreateManagedWidget( "base", glxMDrawWidgetClass,
- bb, wargs, n ) ;
- XtAddCallback( base_widget, GlxNexposeCallback, drawBaseCB, 0 ) ;
- XtAddCallback( base_widget, GlxNginitCallback, initBaseGlCB, 0 ) ;
- n = 4 ;
- XtSetValues( base_widget, wargs, n ) ;
-
- mainviewGlxConfig[1].arg = mv_RGB ;
- n = 0 ;
- XtSetArg( wargs[n], XmNx, VPMVIEW_L ) ; n++ ;
- XtSetArg( wargs[n], XmNy, screen_h - VPMVIEW_T - 1 ) ; n++ ;
- XtSetArg( wargs[n], XmNwidth, VPMVIEW_R - VPMVIEW_L + 1 ) ; n++ ;
- XtSetArg( wargs[n], XmNheight, VPMVIEW_T - VPMVIEW_B + 1 ) ; n++ ;
- XtSetArg( wargs[n], GlxNglxConfig, mainviewGlxConfig ) ; n++ ;
- mainview_widget = XtCreateManagedWidget( "mainview", glxMDrawWidgetClass,
- bb, wargs, n ) ;
- XtAddCallback( mainview_widget, GlxNexposeCallback, drawSceneCB, 0 ) ;
- XtAddCallback( mainview_widget, GlxNginitCallback, initGlCB, 0 ) ;
- n = 4 ;
- XtSetValues( mainview_widget, wargs, n ) ;
- mv_RGB = mainviewGlxConfig[1].arg ;
- if( !mv_RGB ) {
- transparentExplosion = FALSE ;
- use_textures = FALSE ;
- }
-
- n = 0 ;
- XtSetArg( wargs[n], XmNx, VPRADAR_L ) ; n++ ;
- XtSetArg( wargs[n], XmNy, screen_h - VPRADAR_T - 1 ) ; n++ ;
- XtSetArg( wargs[n], XmNwidth, VPRADAR_R - VPRADAR_L + 1 ) ; n++ ;
- XtSetArg( wargs[n], XmNheight, VPRADAR_T - VPRADAR_B + 1 ) ; n++ ;
- if( use_pups ) {
- XtSetArg( wargs[n], GlxNusePopup, TRUE); n++;
- }
- else {
- XtSetArg( wargs[n], GlxNuseOverlay, TRUE ) ; n++ ;
- }
- XtSetArg( wargs[n], GlxNglxConfig, radarviewGlxConfig ) ; n++ ;
- radar_widget = XtCreateManagedWidget( "radar", glxMDrawWidgetClass,
- bb, wargs, n ) ;
- XtAddCallback( radar_widget, GlxNexposeCallback, drawRadarCB, 0 ) ;
- XtAddCallback( radar_widget,
- ( use_pups ) ? GlxNpopupExposeCallback : GlxNoverlayExposeCallback,
- overlayExposeCB, 0);
- XtAddCallback( radar_widget, GlxNginitCallback, initRadarGlCB, 0 ) ;
- n = 4 ;
- XtSetValues( radar_widget, wargs, n ) ;
-
- setTranslations( introTransTable ) ;
-
- picking_tank = TRUE ;
- screen_mode = INTRO_PICK_SCREEN ;
- #endif /* !defined( NETDEBUGGER ) */
-
- init_com();
- if( solo ) {
- set_frame_rate( 2 * DEFAULT_FRAME_RATE ) ;
- }
- else {
- set_frame_rate( DEFAULT_FRAME_RATE ) ;
- }
-
- #if !defined( NETDEBUGGER )
- XtRealizeWidget( toplevel ) ;
- installColormapWithOverlay() ;
- change_cursor() ;
- XtAppMainLoop( appContext ) ;
-
- return( 0 ) ;
- #else
- start_time( ¤t_time ) ;
- init_census_packet( player[SELF].id ) ;
-
- while( 1 ) {
- do_a_time_step() ;
- }
- #endif /* !defined( NETDEBUGGER ) */
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Work process that gets called as soon as all input has been processed.
- *----------------------------------------------------------------------------*/
- static Boolean timeStepWP(
- XtPointer w
- )
- {
- do_a_time_step() ;
- return( FALSE ) ;
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Returns the team with the least number of players (red or blue).
- *----------------------------------------------------------------------------*/
- static int underStaffedTeam( void )
- {
- int i ;
- int red_players = 0 ;
- int blue_players = 0 ;
-
- for( i = ENEMY ; i < number_players ; i++ ) {
- if( player[i].team == RED_TEAM )
- red_players++ ;
- else if( player[i].team == BLUE_TEAM )
- blue_players++ ;
- }
-
- if( red_players < blue_players )
- return( RED_TEAM ) ;
- else if( red_players > blue_players )
- return( BLUE_TEAM ) ;
- else
- return( rand() % 2 ? RED_TEAM : BLUE_TEAM ) ;
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Master loop.
- *----------------------------------------------------------------------------*/
- static void do_a_time_step( void )
- {
- int new_life = 0 ;
- unsigned enemy_id ;
- long status ;
- struct timeval this_time ;
- static float total_time = 0.f ;
- static int nframes = 0 ;
-
- d_time = pace_frame( ¤t_time ) ;
-
- GLXwinset( display, base_window ) ;
-
- if( paused ) {
- if( need_to_show_msgs ) {
- show_msgs( need_to_show_msgs_vocal, msg_redraw ) ;
- need_to_show_msgs = FALSE ;
- msg_redraw = 0 ;
- }
- if( check_pause() )
- sfx( SFX_PAUSE_REMINDER ) ;
- return ;
- }
-
- #if !defined( NETDEBUGGER )
- if( want_to_see_timings ) {
- total_time += d_time ;
- nframes++ ;
- if( total_time >= 1.0f ) {
- post_new_message( 0, 0, "%d frames in %.1f secs.", nframes,
- total_time ) ;
- total_time = 0.0f ;
- nframes = 0 ;
- }
- }
-
- if( name_count < NAME_CHECK_LIMIT ) {
- if( ++name_count == NAME_CHECK_LIMIT )
- check_name();
- }
-
- if( IS_ALIVE( player[SELF] ) ) {
- player[SELF].status = ALIVE_STATUS ;
- act_on_input();
- }
-
- move_em() ;
-
- if( !show_copilot_view )
- collide() ;
-
- write_packets() ;
- read_packets() ;
-
- if( announce_logo ) {
- announce_logo = 0 ;
- if( tank_logo[0] != null_obj ) {
- /*
- * Send out logo packet.
- */
- logo_packet.bz_id = BZLOGO_00 ;
- logo_packet.id = player[SELF].id ;
- send_out( &logo_packet, sizeof( logo_packet ) ) ;
- }
- }
-
- if( view_only && show_copilot_view ) {
- player[SELF].x = player[copilot_player].x ;
- player[SELF].y = player[copilot_player].y ;
- player[SELF].head = player[copilot_player].head ;
- }
-
- /*
- * Update status flag if dead (countdown to reappearance).
- */
- if( IS_DEAD( player[SELF] ) ) {
- status = MAX_DEAD_STATUS - elapsed_sec_tenths( &time_of_death,
- ¤t_time ) ;
- if( status < ALIVE_STATUS ) {
- player[SELF].status = ALIVE_STATUS ;
- }
- else {
- player[SELF].status = status ;
- }
- /*
- * If sending mail, keep status above a certain (dead) level.
- */
- if( sending_msg != SENDING_NO_MAIL ) {
- if( player[SELF].status < MAILING_STATUS ) {
- player[SELF].status = MAILING_STATUS ;
- }
- input_message( 0 ) ;
- }
- /*
- * Not sending mail, check if ready to reappear.
- */
- else if( IS_ALIVE( player[SELF] ) ) {
- /*
- * Reset to minimum death. If not picking tank, get ready to
- * reappear.
- */
- player[SELF].status = MIN_DEAD_STATUS ;
- if( !picking_tank )
- new_life = 1 ;
- }
- }
- else if( sending_msg != SENDING_NO_MAIL ) {
- input_message( 0 ) ;
- }
-
- reshapeviewport() ;
- loadmatrix( id_mat ) ;
- ortho2( -0.5f, (float)screen_w-0.5f, -0.5f, (float)screen_h-0.5f ) ;
-
- show_gun_status( loading_missile - 1 ) ;
- show_speed();
- show_heading();
- if( need_to_show_msgs ) {
- show_msgs( need_to_show_msgs_vocal, msg_redraw ) ;
- need_to_show_msgs = FALSE ;
- msg_redraw = 0 ;
- }
-
- if( need_to_show_lives ) {
- need_to_show_lives = FALSE ;
- show_lives() ;
- }
-
- if( need_to_show_level ) {
- need_to_show_level = FALSE ;
- show_level() ;
- }
-
- if( need_to_show_players ) {
- need_to_show_players = FALSE ;
- show_players() ;
- }
-
- if( need_to_show_out_message ) {
- need_to_show_out_message = FALSE ;
- show_out_message() ;
- }
-
- if( msg_count ) {
- if( --msg_count == 0 ) {
- post_new_message( 50, 0, " " ) ;
- }
- }
-
- if( need_to_show_score ) {
- need_to_show_score = FALSE ;
- show_score() ;
- }
-
- if( need_to_show_mine_st ) {
- need_to_show_mine_st = FALSE ;
- show_mine_status() ;
- }
-
- if( need_to_show_flag_st ) {
- need_to_show_flag_st = FALSE ;
- show_flag_status() ;
- }
-
- if( IS_DEAD( player[SELF] ) && sending_msg == SENDING_NO_MAIL &&
- picking_tank && player[SELF].status < MAILING_STATUS ) {
- player[SELF].status = MAILING_STATUS ;
- }
-
- if( db_base ) {
- swapbuffers();
- }
- else {
- gflush() ;
- }
-
- GLXwinset( display, radar_window ) ;
- radar_view();
- swapbuffers();
-
- if( need_to_show_zoom ) {
- need_to_show_zoom = FALSE ;
- GLXwinset( display, radar_ol_window ) ;
- show_zoom_factor() ;
- }
-
- GLXwinset( display, mainview_window ) ;
- set_up_main_view() ;
- main_view();
- swapbuffers();
-
- if( want_to_identify ) {
- want_to_identify = FALSE ;
- if( ( enemy_id = id_tank() ) ) {
- post_new_message( 0, 0, "Looking at %s.", player[enemy_id].name ) ;
- }
- }
-
- if( want_to_slow_down ) {
- want_to_slow_down = FALSE ;
- sleep( 1 ) ;
- }
-
- if( new_life == 1 ) {
- ol_mode = 0 ;
- if( solo ) {
- adjust_lives() ;
- }
- else {
- lives += 1 ;
- }
- GLXwinset( display, radar_ol_window ) ;
- drawOverlay() ;
- GLXwinset( display, base_window ) ;
- need_to_show_lives = TRUE ;
- setTranslations( mainTransTable ) ;
- if( pick_my_team ) {
- pick_my_team = FALSE ;
- join_a_team( underStaffedTeam() ) ;
- }
- place_self();
- reset_mouse() ;
- }
-
- #else
- write_packets() ;
- read_packets() ;
- #endif /* !defined( NETDEBUGGER ) */
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Redraw the main view.
- *----------------------------------------------------------------------------*/
- void redraw_main_view( void )
- {
- switch( screen_mode ) {
-
- case MAIN_SCREEN :
- main_view() ;
- break ;
-
- case INTRO_PICK_SCREEN :
- case INTRO_SCREEN :
- callobj( mv_black_clear ) ;
- break ;
-
- }
- gflush() ;
- swapbuffers();
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Get the view octant of an object. Return whether or not the object
- * should be culled.
- *----------------------------------------------------------------------------*/
- static int
- getview(
- float x,
- float y,
- float heading,
- unsigned i,
- int *view,
- float xref,
- float yref,
- float cull_head
- )
- {
- float da ;
- float oa ;
- float xx = x - xref ;
- float yy = y - yref;
-
- oa = -getangle( yy, xx ) ;
- da = 720.0f + oa + heading ;
- *view = (int)( da / 45.0f ) % 8 ;
- dst[i] = xx * xx + yy * yy ;
-
- da = fmodf( ( 720.0f - oa - cull_head ), 360.0f ) ;
-
- return( da > max_cull_angle || da < min_cull_angle ) ;
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Return the hypotenuse of a right triangle with sides of x and y.
- *----------------------------------------------------------------------------*/
- float hypotn(
- float x,
- float y
- )
- {
- return( sqrt( x*x + y*y ) ) ;
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Return the sum of the squares of two numbers.
- *----------------------------------------------------------------------------*/
- float square(
- float x,
- float y
- )
- {
- return( x*x + y*y ) ;
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Get the angle (degrees) from atan( y/x ) ;
- *----------------------------------------------------------------------------*/
- float getangle(
- float x,
- float y
- )
- {
- return( fatan2( y, x ) * RAD2DEG ) ;
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Check on missile firing/guiding, tank movement, and other actions.
- *----------------------------------------------------------------------------*/
- void act_on_input( void )
- {
- float dv ;
- float vtop ;
- float ltop ;
- float rtop ;
- float l ;
- float r ;
-
- if( !guiding ) {
- vtop = top_speed ;
- }
- else if( player[SELF].tank_type > 0 ) {
- vtop = gm_vel * (float)player[SELF].msl_status / (float)GM_DURATN ;
- }
- else {
- vtop = 1.2f * gm_vel *
- sqrt( (float)player[SELF].msl_status / (float)GM_DURATN );
- }
-
- dv = vtop * d_time * 4 ;
-
- ltop = left_track_engaged * vtop ;
- rtop = right_track_engaged * vtop ;
- if( ltop < left_track ) {
- left_track -= dv ;
- if( left_track < ltop )
- left_track = ltop ;
- }
- else if( ltop > left_track ) {
- left_track += dv ;
- if( left_track > ltop )
- left_track = ltop ;
- }
- if( rtop < right_track ) {
- right_track -= dv ;
- if( right_track < rtop )
- right_track = rtop ;
- }
- else if( rtop > right_track ) {
- right_track += dv ;
- if( right_track > rtop )
- right_track = rtop ;
- }
-
- if( !guiding ) {
- if( !view_only ) {
- turn_and_go( left_track, right_track,
- &(player[SELF].head), &vx[SELF], &vy[SELF] ) ;
- }
- else {
- turn_and_go( 4.f*left_track, 4.f*right_track,
- &(player[SELF].head), &vx[SELF], &vy[SELF] ) ;
- }
- }
- else {
- l = ( left_track > 0.f ) ? left_track : 0.f ;
- r = ( right_track > 0.f ) ? right_track : 0.f ;
- dv = gm_vel - ( l + r ) / 2.f ;
- l += dv ;
- r += dv ;
- turn_and_go( l, r, &(player[SELF].msl_head), &msl_vx[SELF],
- &msl_vy[SELF] ) ;
- vx[SELF] = vy[SELF] = 0.f ;
- }
-
- if( loading_missile == 0 ) {
- if( fire_normal_missile || fire_guided_missile ) {
- sfx( SFX_FIRE ) ;
- guided_missile = guiding = fire_guided_missile ;
- ricochet = FALSE ;
- if( guiding ) {
- vx[SELF] = vy[SELF] = 0.f ;
- left_track = right_track = gm_vel ;
- reset_mouse() ;
- missile_duration = GM_DURATN ;
- dv = gm_vel ;
- }
- else {
- missile_duration = RM_DURATN ;
- dv = rm_vel ;
- }
- loading_missile = player[SELF].msl_status = missile_duration ;
- copy_time( &missile_launch_time, ¤t_time ) ;
- player[SELF].msl_head = player[SELF].head ;
- turn_and_go( dv, dv, &(player[SELF].msl_head), &msl_vx[SELF],
- &msl_vy[SELF] ) ;
- last_msl_x[SELF] = player[SELF].msl_x = player[SELF].x ;
- last_msl_y[SELF] = player[SELF].msl_y = player[SELF].y ;
- player[SELF].x -= 0.1f * msl_vx[SELF] ;
- player[SELF].y -= 0.1f * msl_vy[SELF] ;
- fire_normal_missile = fire_guided_missile = FALSE ;
- }
- }
- else {
- if( guiding && quit_guided_missile ) {
- left_track = right_track = 0.f ;
- guiding = FALSE ;
- quit_guided_missile = FALSE ;
- reset_mouse() ;
- }
- if( !view_only ) {
- loading_missile = missile_duration -
- elapsed_sec_tenths( &missile_launch_time,
- ¤t_time ) ;
- }
- if( loading_missile <= 0 ) {
- loading_missile = 0 ;
- if( guiding ) {
- left_track = right_track = 0.f ;
- guiding = FALSE ;
- reset_mouse() ;
- }
- }
- }
-
- if( want_to_drop_normal_mine ) {
- want_to_drop_normal_mine = FALSE ;
- drop_mine( 0 ) ;
- }
-
- if( want_to_drop_permanent_mine ) {
- want_to_drop_permanent_mine = FALSE ;
- drop_mine( 1 ) ;
- }
-
- if( want_to_grab_flag ) {
- if( player[SELF].team == RED_TEAM ) {
- try_to_grab_flag( BLUE_FLAG ) ;
- }
- else if( player[SELF].team == BLUE_TEAM ) {
- try_to_grab_flag( RED_FLAG ) ;
- }
- want_to_grab_flag = FALSE ;
- }
-
- if( want_to_drop_flag && HAS_A_FLAG( player[SELF] ) ) {
- player_dropped_flag( &player[SELF] ) ;
- player[SELF].team_flag = 0 ;
- want_to_drop_flag = FALSE ;
- }
- }
-
-
-
- static void try_to_grab_flag(
- int flag_n
- )
- {
- if( square( player[SELF].x - flag_x[flag_n],
- player[SELF].y - flag_y[flag_n] ) < 25.0f ) {
- player[SELF].team_flag = 1 << flag_n ;
- need_to_show_flag_st = TRUE ;
- set_bulletin_color( teamColor[player[SELF].team] ) ;
- post_new_message( 0, 1, "Grabbed %s flag.", ( flag_n == RED_FLAG ) ?
- "red" : "blue" ) ;
- }
- }
-
-
-
- static void drop_mine(
- int permanent
- )
- {
- if( mine_left ) {
- if( show_flags && !red_flag_held &&
- square( player[SELF].x - flag_x[RED_FLAG],
- player[SELF].y - flag_y[RED_FLAG] ) < FLAG_MINE_RADIUS_2 ) {
- post_new_message( 0, 1, "Too close to flag for mine." ) ;
- return ;
- }
- if( show_flags && !blue_flag_held &&
- square( player[SELF].x - flag_x[BLUE_FLAG],
- player[SELF].y - flag_y[BLUE_FLAG] ) < FLAG_MINE_RADIUS_2 ){
- post_new_message( 0, 1, "Too close to flag for mine." ) ;
- return ;
- }
- perm_mine = permanent ;
- post_new_message( 0, 0, "Dropped %s mine.",
- (perm_mine) ? "permanent" : "temporary" ) ;
- mine_left = 0 ;
- mine_x = player[SELF].x ;
- mine_y = player[SELF].y ;
- mine_status = 1 ;
- sfx( SFX_DROP_MINE ) ;
- need_to_show_mine_st = TRUE ;
- }
- }
-
-
-
- void move_em( void )
- {
- long status = 0 ;
-
- player[SELF].x += vx[SELF] * d_time ;
- player[SELF].y += vy[SELF] * d_time ;
-
- if( player[SELF].x < -FIELD_SIZE ) {
- player[SELF].x = -FIELD_SIZE ;
- status = 1 ;
- }
- if( player[SELF].x > FIELD_SIZE ) {
- player[SELF].x = FIELD_SIZE ;
- status = 1 ;
- }
- if( player[SELF].y < -FIELD_SIZE ) {
- player[SELF].y = -FIELD_SIZE ;
- status = 1 ;
- }
- if( player[SELF].y > FIELD_SIZE ) {
- player[SELF].y = FIELD_SIZE ;
- status = 1 ;
- }
-
- if( status == 1 ) {
- blow_up_self( -1 ) ;
- }
-
- if( player[SELF].msl_status > 0 ) {
- last_msl_x[SELF] = player[SELF].msl_x ;
- last_msl_y[SELF] = player[SELF].msl_y ;
- player[SELF].msl_x += msl_vx[SELF] * d_time ;
- player[SELF].msl_y += msl_vy[SELF] * d_time ;
-
- status = 0 ;
- if( player[SELF].msl_x < -FIELD_SIZE ) {
- player[SELF].msl_x = -FIELD_SIZE ;
- status = -1 ;
- }
- if( player[SELF].msl_x > FIELD_SIZE ) {
- player[SELF].msl_x = FIELD_SIZE ;
- status = -1 ;
- }
- if( player[SELF].msl_y < -FIELD_SIZE ) {
- player[SELF].msl_y = -FIELD_SIZE ;
- status = -1 ;
- }
- if( player[SELF].msl_y > FIELD_SIZE ) {
- player[SELF].msl_y = FIELD_SIZE ;
- status = -1 ;
- }
-
- if( !status ) {
- status = missile_duration -
- elapsed_sec_tenths( &missile_launch_time, ¤t_time ) ;
- }
-
- if( status <= 0 ) {
- player[SELF].msl_status = -MEXPL_DURATION ;
- copy_time( &missile_explode_time, ¤t_time ) ;
- explosion_sfx( player[SELF].msl_x - player[SELF].x,
- player[SELF].msl_y - player[SELF].y,
- player[SELF].head ) ;
- if( guiding ) {
- left_track = right_track = 0.f ;
- guiding = FALSE ;
- reset_mouse() ;
- }
- }
- else {
- player[SELF].msl_status = status ;
- }
- }
- else if( player[SELF].msl_status < 0 ) {
- status = -MEXPL_DURATION
- + elapsed_sec_tenths( &missile_explode_time, ¤t_time ) ;
- if( status >= 0 ) {
- player[SELF].msl_status = 0 ;
- }
- else {
- player[SELF].msl_status = status ;
- }
- }
- }
-
-
- float xp[TOTALOBSTS] = { 0.,-2., 2.,-2., 2.,-2., 2., 0.,-4.,-4., 4., 4.,
- -3., 3.,-1., 1.,-1., 1.,-3., 3.,-4., 4., 0., 0. } ;
- float yp[TOTALOBSTS] = { 2., 2., 2., 0., 0.,-2.,-2.,-2.,-4., 4.,-4., 4.,
- 3., 3., 1., 1.,-1.,-1.,-3.,-3., 0., 0.,-4., 4. } ;
-
- void init_var( void )
- {
- unsigned i ;
-
- char_width = (float)strwidth( "ABCDEFGHIJKLM" ) / 13.f ;
- char_height = (float)getheight() ;
-
- screen_mode = INTRO_SCREEN ;
-
- XtAppAddWorkProc( appContext, randomizerWP, 0 ) ;
- randomizer = True ;
-
- reset_viewing_order() ;
- for( i = 0 ; i < TOTALOBSTS ; i++ ) {
- obst_x[i] = (float)OBJECT_SPACING * xp[i] ;
- obst_y[i] = (float)OBJECT_SPACING * yp[i] ;
- head[i] = 0 ;
- }
-
- flag_x[RED_FLAG] = RED_FLAG_HOME_X ;
- flag_y[RED_FLAG] = RED_FLAG_HOME_Y ;
- flag_x[BLUE_FLAG] = BLUE_FLAG_HOME_X ;
- flag_y[BLUE_FLAG] = BLUE_FLAG_HOME_Y ;
-
- vx[SELF] = vy[SELF] = 0.f ;
- player[SELF].bz_id = BZ ;
- player[SELF].msl_x = player[SELF].msl_y = msl_vx[SELF] = msl_vy[SELF] = 0.f;
- player[SELF].status = ALIVE_STATUS ;
- player[SELF].msl_head = player[SELF].msl_status = 0 ;
- }
-
-
-
- void place_self( void )
- {
- int j ;
- int k ;
- float r ;
- float ang ;
- float cx ;
- float cy ;
- int team_members ;
-
- if( need_to_set_tank ) {
- need_to_set_tank = FALSE ;
- player[SELF].tank_type = new_tank_type ;
- }
-
- team_members = 0 ;
- cx = cy = 0.0f ;
- if( player[SELF].team != NEUTRAL_TEAM && !init_wait ) {
- for( k = ENEMY ; k < number_players ; k++ ) {
- if( IS_ALIVE( player[k] ) && player[k].team == player[SELF].team ) {
- cx += player[k].x ;
- cy += player[k].y ;
- team_members++ ;
- }
- }
- if( team_members > 0 ) {
- cx /= (float)team_members ;
- cy /= (float)team_members ;
- }
- }
-
- do{
- j = 0 ;
- if( !init_wait ) {
- r = (float)OBJECT_SPACING +
- fmodf( (float)( rand() ), FIELD_SIZE - OBJECT_SPACING - 50.f ) ;
- }
- else {
- r = (float)( rand() % OBJECT_SPACING ) ;
- }
- ang = rand() % 360 ;
- player[SELF].x = cx + r * COSINE(ang) ;
- player[SELF].y = cy + r * SINE(ang) ;
- r = 0.9f * FIELD_SIZE ;
- if( player[SELF].x < -r ) player[SELF].x = -r ;
- if( player[SELF].y < -r ) player[SELF].y = -r ;
- if( player[SELF].x > r ) player[SELF].x = r ;
- if( player[SELF].y > r ) player[SELF].y = r ;
- for( k = 0 ; k < TOTALOBSTS ; k++ ) {
- if( square( player[SELF].x-obst_x[k], player[SELF].y-obst_y[k] )
- < 1600.f )
- j = 1 ;
- }
- } while( j != 0 );
- player[SELF].head = ( rand() % 3600 ) / 10.f ;
- player[SELF].status = ALIVE_STATUS ;
- player[SELF].killed_by_id = 0 ;
- if( !perm_mine ) {
- mine_left = 1 ;
- mine_status = 0 ;
- need_to_show_mine_st = TRUE ;
- }
- if( !init_wait ) {
- loading_missile = 2 ;
- copy_time( &missile_launch_time, ¤t_time ) ;
- missile_duration = GM_DURATN / 10 ;
- }
- else {
- missile_duration = loading_missile = GM_DURATN ;
- start_time( &missile_launch_time ) ;
- }
- top_speed = vmax[player[SELF].tank_type] ;
- sfx( SFX_POP ) ;
- }
-
-
-
- void set_up_main_view( void )
- {
- int i ;
- int kk ;
- int culled ;
- long status ;
- int view ;
- float xref ;
- float yref ;
- float href ;
-
- n_view_objs = 0 ;
-
- if( !guiding ) {
- xref = player[SELF].x ;
- yref = player[SELF].y ;
- href = player[SELF].head ;
- }
- else {
- xref = player[SELF].msl_x ;
- yref = player[SELF].msl_y ;
- href = player[SELF].msl_head ;
- }
-
- for( i = CONES ; i < CUBES ; i++, n_view_objs++ ) {
- if( getview( obst_x[i], obst_y[i], head[i], n_view_objs, &view,
- xref, yref, href ) )
- view_object[n_view_objs] = pyrm[view] ;
- else
- view_object[n_view_objs] = null_obj ;
- }
-
- for( i = CUBES ; i < TOTALOBSTS ; i++, n_view_objs++ ) {
- if( getview( obst_x[i], obst_y[i], head[i], n_view_objs, &view,
- xref, yref, href ) )
- view_object[n_view_objs] = cube[view] ;
- else
- view_object[n_view_objs] = null_obj ;
- }
-
- for( i = 0 ; i < N_FLAGS ; i++, n_view_objs++ ) {
- if( show_flags ) {
- if( getview( flag_x[i], flag_y[i], 0.f, n_view_objs, &view,
- xref, yref, href ) ) {
- view_object[n_view_objs] = flag[i][view] ;
- }
- else {
- view_object[n_view_objs] = null_obj ;
- }
- }
- else {
- dst[n_view_objs] = 0.f ;
- view_object[n_view_objs] = null_obj ;
- }
- }
-
- for( i = SELF ; i < number_players ; i++, n_view_objs += 2 ) {
- if( i != SELF ) {
- culled = getview( player[i].x, player[i].y, player[i].head,
- n_view_objs, &view, xref, yref, href ) ;
- if( IS_DEAD( player[i] ) ) {
- kk = MAX_DEAD_STATUS - player[i].status ;
- if( kk >= EXPDURATION )
- kk = EXPDURATION - 1 ;
- view_object[n_view_objs] = ( culled ) ?
- explosion[player[i].team][kk][tank_body[player[i].tank_type]] :
- null_obj ;
- }
- else {
- view_object[n_view_objs] = ( culled ) ?
- view + 1 : null_obj ;
- }
- }
- else {
- dst[n_view_objs] = 0.f ;
- view_object[n_view_objs] = null_obj ;
- }
-
- if( player[i].msl_status ) {
- culled = getview( player[i].msl_x, player[i].msl_y,
- player[i].msl_head, n_view_objs+1, &view,
- xref, yref, href ) ;
- if( player[i].msl_status > 0 ) {
- view_object[n_view_objs+1] = ( culled ) ?
- missile[view] : null_obj ;
- }
- else {
- player[i].msl_head = player[SELF].head ;
- view_object[n_view_objs+1] = ( culled ) ?
- msl_expl[MEXPL_DURATION+player[i].msl_status] :
- null_obj ;
- }
- }
- else {
- dst[n_view_objs+1] = 0.f ;
- view_object[n_view_objs+1] = null_obj ;
- }
- }
-
- sort_view( n_view_objs ) ;
- }
-
-
-
- void main_view( void )
- {
- #if !defined( NETDEBUGGER )
- float xx ;
- float yy ;
- unsigned i ;
- unsigned j ;
- unsigned l ;
- unsigned m ;
- int kk ;
- long teamScore[N_TEAMS] ;
- char info[100] ;
-
- reshapeviewport() ;
- loadmatrix( id_mat ) ;
- ortho2( 0.f, mv_w, 0.f, mv_h ) ;
-
- if( guiding )
- callobj( mv_guided_bg ) ;
- else
- callobj( mv_normal_bg ) ;
-
- if( binoculars && !guiding ) {
- perspective( 30, aspect_ratio, .5f, 10000.f ) ;
- }
- else {
- perspective( 300, aspect_ratio, .5f, 10000.f ) ;
- }
-
- rotate( -900, 'x' ) ;
-
- if( guiding )
- rot( player[SELF].msl_head, 'z' );
- else
- rot( player[SELF].head, 'z' );
-
- callobj( sky ) ;
-
- if( mv_RGB ) {
- callobj( lights_on ) ;
- }
-
- pushmatrix() ;
- if( guiding )
- translate( -fmodf(player[SELF].msl_x, 50.f ),
- -fmodf(player[SELF].msl_y, 50.f ), -DROP ) ;
- else
- translate( -fmodf(player[SELF].x, 50.f ),
- -fmodf(player[SELF].y, 50.f ), -DROP ) ;
- callobj( ground ) ;
- popmatrix() ;
-
- if( guiding )
- translate( -player[SELF].msl_x, -player[SELF].msl_y, -DROP ) ;
- else
- translate( -player[SELF].x, -player[SELF].y, -DROP ) ;
-
- callobj( border ) ;
-
- if( show_flags ) {
- callobj( flag_homes_mv ) ;
- }
-
- for( i = n_view_objs - 1 ; i >= 0 ; i-- ) {
- j = l = view_order[i] ;
- if( view_object[j] != null_obj ) {
- if( j < TOTALOBSTS ) {
- tran_rot_show( obst_x[j], obst_y[j], head[j], view_object[j] ) ;
- }
- else {
- l -= TOTALOBSTS ;
- if( l < N_FLAGS ) {
- tran_rot_show( flag_x[l], flag_y[l], 0.f, view_object[j] ) ;
- }
- else {
- l -= N_FLAGS ;
- /*
- * if l==0, it is SELF, so don't show
- */
- if( l > 0 ) {
- m = l / 2 ;
- if( l % 2 ) {
- if( m != SELF || !guiding ) {
- tran_rot_show( player[m].msl_x, player[m].msl_y,
- player[m].msl_head,
- view_object[j] ) ;
- }
- }
- else {
- if( IS_DEAD( player[m] ) ||
- view_object[j] == null_obj ) {
- tran_rot_show( player[m].x, player[m].y,
- player[m].head, view_object[j] );
- }
- else {
- pushmatrix() ;
- translate( player[m].x, player[m].y, 0.f ) ;
- rot( -player[m].head, 'z' ) ;
- draw_tank( tank_body[player[m].tank_type],
- view_object[j] - 1,
- player[m].team, m ) ;
- popmatrix() ;
- }
- }
- }
- }
- }
- }
- else if( dst[j] == 0.0f ) {
- break ;
- }
- }
-
- if( mv_RGB ) {
- callobj( lights_off ) ;
- }
-
- callobj( crosshairs );
- if( IS_DEAD( player[SELF] ) || want_to_see_score || want_to_see_help ) {
- loadmatrix( id_mat ) ;
- ortho2( 0.f, 1024.f, 0.f, 550.f ) ;
-
- if( IS_DEAD( player[SELF] ) ) {
- linewidth(3);
- callobj( mv_set_white );
- kk = MAX_DEAD_STATUS - player[SELF].status ;
- for( i=0 ; i < kk ; i++ ) {
- if( i < 30 ) {
- bgnline() ;
- v2f( fracture[i].v0 ) ;
- v2f( fracture[i].v1 ) ;
- endline() ;
- }
- }
- linewidth(1);
- }
-
- ortho2( 0.f, mv_w, 0.f, mv_h ) ;
-
- /*
- * Show help.
- */
- if( want_to_see_help ) {
- callobj( mv_set_red );
- print_help( mv_w / 2.f, mv_h / 2.f, 0 ) ;
- }
- /*
- * Show scores
- */
- else if ( !solo ) {
- callobj( mv_set_yellow );
- xx = ( mv_w - 6.f*char_width ) / 2.f ;
- yy = mv_h - 40.f ;
- cmov2( xx, yy ) ;
- charstr( "SCORES" ) ;
- xx = ( mv_w - 30.f*char_width ) / 2.f ;
- yy -= 20.f ;
- teamScore[NEUTRAL_TEAM] = teamBonus[NEUTRAL_TEAM] ;
- teamScore[RED_TEAM] = teamBonus[RED_TEAM] ;
- teamScore[BLUE_TEAM] = teamBonus[BLUE_TEAM] ;
- for( i = ( view_only ) ? 1 : 0 ; i < number_players ;
- i++, yy -= 20.f ) {
- sprintf( info, "%-12s %6d %8s", player[i].name,
- player[i].score, teamName[player[i].team] );
- cmov2( xx, yy ) ;
- charstr( info ) ;
- teamScore[player[i].team] += player[i].score ;
- }
- xx = ( mv_w - 11.f*char_width ) / 2.f ;
- yy -= 20.f ;
- cmov2( xx, yy ) ;
- charstr( "TEAM TOTALS" ) ;
- xx = ( mv_w - 15.f*char_width ) / 2.f ;
- yy -= 20.f ;
- for( i = 0 ; i < N_TEAMS ; i++, yy -= 20.f ) {
- sprintf( info, "%-7s %6d", teamName[i], teamScore[i] ) ;
- cmov2( xx, yy ) ;
- charstr( info ) ;
- }
- }
- }
-
- #endif /* !defined( NETDEBUGGER ) */
- }
-
-
- void sort_view(
- int k
- )
- {
- qsort( (char *)(&view_order[0]), k, sizeof(view_order[0]), cmpfnc ) ;
- }
-
-
-
- int cmpfnc(
- const void *ep1,
- const void *ep2
- )
- {
- if( dst[*((unsigned int *)ep1)] > dst[*((unsigned int *)ep2)] ) {
- return(1) ;
- }
- else {
- return(-1) ;
- }
- }
-
-
- void turn_and_go(
- float l,
- float r,
- float *heading,
- float *velx,
- float *vely
- )
- {
- float v ;
- v = ( l + r ) / 2.f ;
- *heading += ( ( l - r ) * t_factor * d_time ) ;
- *heading = fmodf( *heading, 360.0f ) ;
- *heading = ( *heading < 0 ) ? *heading + 360.0f : *heading ;
- *velx = v*SINE( *heading ) ;
- *vely = v*COSINE( *heading ) ;
- }
-
-
-
- void collide( void )
- {
- unsigned hit ;
- unsigned obst_id ;
- float xhit ;
- float yhit ;
- float radius ;
- unsigned enemy_id ;
- int mine_flag ;
- int side ;
-
- hit = 0 ;
-
- if( hit_count ) {
- hit_count = MAX_HIT_COUNT
- - elapsed_sec_tenths( &hit_time, ¤t_time ) ;
- if( hit_count < 0 ) {
- hit_count = 0 ;
- player[SELF].hit_by_id = 0 ;
- }
- }
-
- if( player[SELF].msl_status > 0 ) {
- switch( check_missile_hit( SELF, &enemy_id, &side ) ) {
- case 1:
- if( enemy_id != SELF || ricochet ) {
- if( guiding ) {
- left_track = right_track = 0.f ;
- guiding = FALSE ;
- reset_mouse() ;
- }
- explosion_sfx( player[SELF].msl_x - player[SELF].x,
- player[SELF].msl_y - player[SELF].y,
- player[SELF].head ) ;
- player[SELF].msl_status = -MEXPL_DURATION ;
- copy_time( &missile_explode_time, ¤t_time ) ;
- player[SELF].msl_x = player[enemy_id].x ;
- player[SELF].msl_y = player[enemy_id].y ;
- msl_vx[SELF] = msl_vy[SELF] = 0.f ;
- player[SELF].hit_type = HIT_BY_MISSILE ;
- if( enemy_id == SELF ) {
- blow_up_self( 0 ) ;
- }
- else {
- player[SELF].hit_by_id = player[enemy_id].id ;
- hit_count = MAX_HIT_COUNT ;
- copy_time( &hit_time, ¤t_time ) ;
- }
- }
- break;
- case 2:
- if( guided_missile ){
- if( guiding ){
- left_track = right_track = 0.f ;
- guiding = FALSE ;
- reset_mouse() ;
- }
- player[SELF].msl_status = -MEXPL_DURATION ;
- copy_time( &missile_explode_time, ¤t_time ) ;
- player[SELF].msl_x -= msl_vx[SELF] * d_time ;
- player[SELF].msl_y -= msl_vy[SELF] * d_time ;
- msl_vx[SELF] = msl_vy[SELF] = 0.f ;
- explosion_sfx( player[SELF].msl_x - player[SELF].x,
- player[SELF].msl_y - player[SELF].y,
- player[SELF].head ) ;
- }
- else {
- player[SELF].msl_x -= msl_vx[SELF] * d_time ;
- player[SELF].msl_y -= msl_vy[SELF] * d_time ;
- switch( side ) {
- case MIN_X_SIDE :
- case MAX_X_SIDE :
- msl_vx[SELF] = -msl_vx[SELF] ;
- break ;
- case MIN_Y_SIDE :
- case MAX_Y_SIDE :
- msl_vy[SELF] = -msl_vy[SELF] ;
- break ;
- }
- player[SELF].msl_head = getangle( msl_vy[SELF],
- msl_vx[SELF] ) ;
- ricochet = TRUE ;
- }
- break;
- case 0:
- default:
- break;
- }
- }
-
- /*
- * Check for mine interaction.
- */
- if( mine_status > 0 ) {
- /*
- * If player is alive and not detonating mine, or if player has a
- * permanent mine, check for normal kill radius.
- */
- if( ( IS_ALIVE( player[SELF] ) &&
- !( mine_flag = want_to_detonate_mine ) ) || perm_mine ) {
- radius = REG_MINE_RADIUS * REG_MINE_RADIUS ;
- }
- /*
- * Otherwise, player is detonating the mine, so increase the kill
- * radius.
- */
- else {
- radius = DET_MINE_RADIUS * DET_MINE_RADIUS ;
- mine_status = 0 ;
- if( mine_flag ) {
- if( no_sfx )
- ringbell() ;
- else
- explosion_sfx( mine_x - player[SELF].x,
- mine_y - player[SELF].y,
- player[SELF].head ) ;
- mine_left = 1 ;
- need_to_show_mine_st = TRUE ;
- }
- }
- /*
- * Check if mine hit any enemy tanks, or self.
- */
- switch( check_mine_hit( &enemy_id, radius ) ) {
- /*
- * Hit a tank.
- */
- case 1:
- /*
- * Hit an enemy's tank.
- */
- if( enemy_id ) {
- if( IS_ALIVE( player[enemy_id] ) ) {
- mine_status = 0 ;
- player[SELF].hit_by_id = player[enemy_id].id ;
- player[SELF].hit_type = HIT_BY_MINE ;
- hit_count = MAX_HIT_COUNT ;
- copy_time( &hit_time, ¤t_time ) ;
- if( !solo )
- level++ ;
- need_to_show_level = TRUE ;
- mine_left = 1;
- need_to_show_mine_st = TRUE ;
- }
- }
- /*
- * Close enough to pick up, if so desired.
- */
- else if( want_to_pick_mine ) {
- post_new_message( 0, no_sfx, "Picked up mine." ) ;
- mine_left = 1 ;
- mine_status = 0 ;
- perm_mine = 0 ;
- sfx( SFX_PICK_UP_MINE ) ;
- need_to_show_mine_st = TRUE ;
- }
- want_to_pick_mine = FALSE ;
- break;
- /*
- * Nothing hit.
- */
- default:
- want_to_pick_mine = FALSE ;
- break;
- }
- want_to_detonate_mine = FALSE ;
- }
-
- if( IS_ALIVE( player[SELF] ) ) {
- /*
- * Check to hit enemy tanks and obstacles.
- */
- switch( check_tank_collision( SELF, &obst_id ) ) {
- /*
- * Hit an enemy tank (obst_id).
- */
- case 1:
- hit = 1 ;
- xhit = player[obst_id].x ;
- yhit = player[obst_id].y ;
- break;
- /*
- * Hit an obstacle (obst_id).
- */
- case 2:
- hit = 1 ;
- xhit = obst_x[obst_id] ;
- yhit = obst_y[obst_id] ;
- break;
- /*
- * Hit nothing.
- */
- case 0:
- default:
- break;
- }
- }
-
- if( hit ) {
- sfx( SFX_BUMP ) ;
- move_after_hit( SELF, xhit, yhit, vx[SELF], vy[SELF] ) ;
- }
-
- }
-
-
-
- void move_after_hit(
- unsigned int tank_id,
- float xhit,
- float yhit,
- float velx,
- float vely
- )
- {
- float dx ;
- float dy ;
- float d ;
- float dv ;
-
- dx = player[tank_id].x - xhit ;
- dy = player[tank_id].y - yhit ;
- d = hypotn( dx, dy ) ;
- if( d != 0.0f ) {
- dv = 0.1f * vmax[player[tank_id].tank_type] ;
- player[tank_id].x += dv * dx / d - velx * d_time ;
- player[tank_id].y += dv * dy / d - vely * d_time ;
- }
- else {
- player[tank_id].x -= 2 * velx * d_time ;
- player[tank_id].y -= 2 * vely * d_time ;
- }
- }
-
-
-
- void vertex2f(
- float x,
- float y
- )
- {
- float pt[2] ;
-
- pt[0] = x ;
- pt[1] = y ;
- v2f( pt ) ;
- }
-
-
-
- static char *service_msg[] = {
- "Can't find udp service \"sgi-bznet\"\n\n",
- "To run bz over the network, you must have the following line\n",
- "in your /etc/services file.\n\n",
- "sgi-bznet\t5133/udp\t\t# tank demo\n\n",
- } ;
-
-
- void init_com( void )
- {
- #if !defined( NETDEBUGGER )
- int i ;
- int port ;
- int id ;
- struct servent *serv ;
-
- if( solo ) {
- networking = FALSE ;
- write_packets = do_enemy_stuff ;
- read_packets = no_op ;
- }
- else if( in_name == NULL && out_name == NULL ) {
-
- if( ( serv = getservbyname( BZ_SERVICE, NULL ) ) == NULL ) {
- for( i = 0 ; i < sizeof( service_msg ) / sizeof( service_msg[0] ) ;
- i++ ) {
- fputs( service_msg[i], stderr ) ;
- }
- system("inform 'Sorry, you must change the line in /etc/services to allow bz to work in network mode: otherwise use bz -solo'");
- end_program( 1 );
- }
- port = serv->s_port ;
-
- #if defined( BETA )
- port = 5134 ;
- #endif /* defined( BETA ) */
-
- if( timeToLive < BZ_MIN_TTL || timeToLive > BZ_MAX_TTL ) {
- fprintf( stderr, "Specified time-to-live (%d) does not fall within"
- " acceptable range (%d - %d).\n", timeToLive, BZ_MIN_TTL,
- BZ_MAX_TTL );
- fprintf( stderr, "The default value of %d will be used.\n",
- BZ_DEFAULT_TTL ) ;
- timeToLive = BZ_DEFAULT_TTL ;
- }
-
- if( ( in_fd = openMulticastSocket( &in_addr, port, timeToLive, 0,
- BZ_GROUP, NULL, "r" ) ) < 0 ) {
- end_program( 1 ) ;
- }
- read_packets = network_in ;
-
- /*
- * Turn on non-blocking I/O
- */
- if( fcntl( in_fd, F_SETFL, FNDELAY ) < 0 ) {
- perror( "fcntl F_SETFL, FNDELAY" ) ;
- end_program( 1 ) ;
- }
-
- if( view_only ) {
- write_packets = no_op ;
- out_fd = -1 ;
- }
- else {
- if( ( out_fd = openMulticastSocket( &out_addr, port, timeToLive, 0,
- BZ_GROUP, NULL, "w" ) ) < 0 ) {
- end_program( 1 ) ;
- }
- out_addrlen = sizeof( out_addr ) ;
- write_packets = network_out ;
- }
- }
- else {
- if( in_name != NULL ) {
- if( ( in_fd = open( in_name, O_RDONLY ) ) == -1 ) {
- perror( in_name ) ;
- end_program( 1 ) ;
- }
- else {
- if( read( in_fd, &id, sizeof( id ) ) != sizeof( id ) ) {
- perror( in_name ) ;
- end_program( 1 ) ;
- }
- if( id != BZ ) {
- fprintf( stderr, "%s: input file `%s' is not from this"
- " version of %s.\n", basename, in_name,
- basename ) ;
- end_program( 1 ) ;
- }
- else {
- lseek( in_fd, 0, 0 ) ;
- }
- }
- read_packets = file_in ;
- }
- else {
- read_packets = no_op ;
- in_fd = -1 ;
- }
-
- if( out_name != NULL ) {
- if( ( out_fd = open( out_name, O_WRONLY|O_CREAT|O_TRUNC, 0644 ) )
- == -1 ) {
- perror( out_name ) ;
- end_program( 1 ) ;
- }
- write_packets = file_out ;
- }
- else {
- write_packets = no_op ;
- out_fd = -1 ;
- }
-
- }
- #else
- write_packets = net_debug_out ;
- read_packets = net_debug_in ;
- in_fd = 0 ;
- out_fd = 1 ;
- read( 0, player[SELF].name, sizeof( player[SELF].name ) ) ;
- read( 0, &player[SELF].id, sizeof( player[SELF].id ) ) ;
- player[SELF].bz_id = BZ ;
- post_new_message( 0, 0, "initiated as %s with an id of %d.",
- player[SELF].name, player[SELF].id ) ;
- /*
- * Turn on non-blocking I/O
- */
- if( fcntl( 0, F_SETFL, FNONBLK ) < 0 ) {
- fprintf( stderr, "player %s: fcntl F_SETFL, FNONBLK\n",
- player[SELF].name ) ;
- exit( 1 ) ;
- }
- #endif /* !defined( NETDEBUGGER ) */
-
- }
-
-
-
- void no_op( void )
- {
- }
-
-
-
- void file_out( void )
- {
- int i ;
-
- for( i = number_players ; i-- ; ) {
- if( write( out_fd, (void *)(&player[i]), sizeof(struct BzMember) ) <
- sizeof(struct BzMember) ) {
- perror("file_out");
- end_program(0);
- }
- }
- }
-
-
-
- void process_players( void )
- {
- int i ;
-
- red_flag_held = blue_flag_held = FALSE ;
-
- for( i = ENEMY ; i < number_players ; i++ ) {
- activity[i] -= 1 ;
- if( activity[i] < 0 ) {
- drop_host( player[i].id ) ;
- delete_player( i, "was dropped" ) ;
- }
- else if( !never_have_flag ) {
- if( player[i].team == RED_TEAM ) {
- if( HAS_BLUE_FLAG( player[i] ) ) {
- blue_flag_held = TRUE ;
- flag_x[BLUE_FLAG] = player[i].x ;
- flag_y[BLUE_FLAG] = player[i].y ;
- }
- }
- else if( player[i].team == BLUE_TEAM ) {
- if( HAS_RED_FLAG( player[i] ) ) {
- red_flag_held = TRUE ;
- flag_x[RED_FLAG] = player[i].x ;
- flag_y[RED_FLAG] = player[i].y ;
- }
- }
- }
- if( hit_by[i] ) {
- hit_by[i] = MAX_HIT_BY_COUNT
- - elapsed_sec_tenths( &time_of_death, ¤t_time ) ;
- if( hit_by[i] < 0 )
- hit_by[i] = 0 ;
- }
- }
-
- if( !never_have_flag ) {
- if( player[SELF].team == RED_TEAM ) {
- if( HAS_BLUE_FLAG( player[SELF] ) ) {
- if( blue_flag_held ) {
- set_bulletin_color( teamColor[BLUE_TEAM] ) ;
- post_new_message( 0, 1, "BLUE FLAG CONFLICT!!!" ) ;
- player[SELF].team_flag = 0 ;
- player_dropped_flag( &player[SELF] ) ;
- }
- else {
- blue_flag_held = TRUE ;
- flag_x[BLUE_FLAG] = player[SELF].x ;
- flag_y[BLUE_FLAG] = player[SELF].y ;
- }
- }
- }
- else if( player[SELF].team == BLUE_TEAM ) {
- if( HAS_RED_FLAG( player[SELF] ) ) {
- if( red_flag_held ) {
- set_bulletin_color( teamColor[RED_TEAM] ) ;
- post_new_message( 0, 1, "RED FLAG CONFLICT!!!" ) ;
- player[SELF].team_flag = 0 ;
- player_dropped_flag( &player[SELF] ) ;
- }
- else {
- red_flag_held = TRUE ;
- flag_x[RED_FLAG] = player[SELF].x ;
- flag_y[RED_FLAG] = player[SELF].y ;
- }
- }
- }
- }
- }
-
-
-
- int read_rest_of_file_packet(
- void *packet,
- int size
- )
- {
- int nc_read ;
-
- size -= sizeof( BzId ) ;
-
- if( ( nc_read = read( in_fd, (char *)packet + sizeof( BzId ), size ) )
- != size ) {
- return( nc_read ) ;
- }
- else {
- return( 0 ) ;
- }
- }
-
-
-
- void file_in( void )
- {
- int no_chars_read ;
- union BzPacket packet ;
- struct BzMember input ;
- int st = 0 ;
- int i ;
- int number ;
-
- i = 1 ;
- do {
- if( ( no_chars_read =
- read( in_fd, &(packet.bz_id), sizeof(packet.bz_id) )
- ) == sizeof(packet.bz_id) ) {
- switch( packet.bz_id ) {
- case BZ :
- i++ ;
- if( ( st = read_rest_of_file_packet( &packet,
- sizeof( packet.member ) ) ) == 0 ) {
- packet.member.id++ ;
- if( valid_keyed_host( packet.member.id,
- packet.member.key ) ) {
- process_bz_packet( &(packet.member) ) ;
- }
- }
- break ;
-
- case BZMSG :
- if( ( st = read_rest_of_file_packet( &packet,
- sizeof( packet.notice ) ) ) == 0 ) {
- packet.notice.id++ ;
- process_bz_notice( &(packet.notice), NEUTRAL_TEAM ) ;
- }
- break ;
-
- case BZREDMSG :
- if( ( st = read_rest_of_file_packet( &packet,
- sizeof( packet.notice ) ) ) == 0 ) {
- packet.notice.id++ ;
- process_bz_notice( &(packet.notice), RED_TEAM ) ;
- }
- break ;
-
- case BZBLUEMSG :
- if( ( st = read_rest_of_file_packet( &packet,
- sizeof( packet.notice ) ) ) == 0 ) {
- packet.notice.id++ ;
- process_bz_notice( &(packet.notice), BLUE_TEAM ) ;
- }
- break ;
-
- case BZLOGO_00 :
- if( ( st = read_rest_of_file_packet( &packet,
- sizeof( packet.logo ) ) ) == 0 ) {
- packet.logo.id++ ;
- if( ( number = find_player( packet.logo.id ) ) > 0 &&
- tank_logo[number] == null_obj ) {
- tank_logo[number] =
- create_logo( packet.logo.logo_info, 1,
- &(tank_logo_side[number]) ) ;
- if( write_packets == file_out ) {
- send_to_file( &(packet.logo),
- sizeof( packet.logo ) ) ;
- }
- }
- }
- break ;
-
- case BZQUIT :
- if( ( st = read_rest_of_file_packet( &packet,
- sizeof( packet.ack ) ) ) == 0 ) {
- if( ( number = find_player( packet.ack.id ) ) > 0 ) {
- remove_host( packet.ack.id ) ;
- delete_player( number, "quit" ) ;
- }
- }
- break ;
-
- case BZACK :
- case BZINVALIDATE :
- st = read_rest_of_file_packet( &packet,
- sizeof( packet.ack ) ) ;
- break ;
-
- default :
- fprintf( stderr, "%s: unknown packet type received in %s.",
- basename, in_name ) ;
- end_program( 1 ) ;
- break ;
- }
- if( st ) {
- fprintf( stderr, "%s: bad packet read from %s.", basename,
- in_name ) ;
- end_program( 1 ) ;
- }
- }
- else if( no_chars_read == 0 ) {
- if( lseek( in_fd, 0, SEEK_SET ) != 0 ) {
- write_packets = no_op ;
- }
- }
- else {
- perror( in_name ) ;
- end_program( 1 ) ;
- }
- } while( i < number_players ) ;
-
- process_players() ;
- }
-
-
-
-
-
-
- void process_bz_packet(
- struct BzMember *input
- )
- {
- int number ;
- int killer ;
- int score_mod ;
-
- /* either update existing player or create a new one */
- if( !( number = find_player( input->id ) ) ) {
- add_player( &number ) ;
- copy_player( number, input ) ;
- check_id( number ) ;
- set_bulletin_color( teamColor[input->team] ) ;
- post_new_message( 0, 1, "Added %s to %s team.", input->name,
- teamName[input->team] ) ;
- #if defined( NETDEBUGGER )
- show_player_list() ;
- #endif /* defined( NETDEBUGGER ) */
- if( networking && !view_only ) {
- announce_logo = 1 ;
- add_host_to_census( input->id ) ;
- }
- if( !show_flags && !never_have_flag ) {
- if( input->team == RED_TEAM ) {
- red_team_present = TRUE ;
- }
- else if( input->team == BLUE_TEAM ) {
- blue_team_present = TRUE ;
- }
- if( red_team_present && blue_team_present ) {
- show_flags = TRUE ;
- post_new_message( 0, 1, "Flag capturing enabled." ) ;
- }
- }
- }
-
- activity[number] = MAX_ACTIVITY ;
-
- /*
- * If player team changes....
- */
- if( input->team != player[number].team ) {
- set_bulletin_color( teamColor[input->team] ) ;
- post_new_message( 0, 1, "%s switched to %s team.", player[number].name,
- teamName[input->team] ) ;
- if( !show_flags && !never_have_flag ) {
- if( input->team == RED_TEAM ) {
- red_team_present = TRUE ;
- }
- else if( input->team == BLUE_TEAM ) {
- blue_team_present = TRUE ;
- }
- if( red_team_present && blue_team_present ) {
- show_flags = TRUE ;
- post_new_message( 0, 1, "Flag capturing enabled." ) ;
- }
- }
- }
-
- /*
- * If player is transitioning from alive to dead...
- */
- if( IS_DEAD( *input ) && IS_ALIVE( player[number] ) ) {
- explosion_sfx( input->x - player[SELF].x,
- input->y - player[SELF].y, player[SELF].head ) ;
- if( input->killed_by_id == player[SELF].id ||
- input->id == player[SELF].hit_by_id ) {
- level++ ;
- need_to_show_level = TRUE ;
- player[SELF].hit_by_id = 0 ;
- if( player[SELF].team != 0 &&
- player[SELF].team == input->team ) {
- score_mod = -1 ;
- set_bulletin_color( teamColor[input->team] ) ;
- post_new_message( 0, no_sfx, "Oops, killed %s.",
- input->name ) ;
- }
- else {
- score_mod = 1 ;
- post_new_message( 0, no_sfx, "Killed %s.", input->name ) ;
- }
- switch( input->tank_type ) {
- case 0:
- player[SELF].score += 50 * score_mod ;
- break ;
- case 1:
- player[SELF].score += 75 * score_mod ;
- break ;
- case 2:
- player[SELF].score += 100 * score_mod ;
- break ;
- case 3:
- player[SELF].score += 125 * score_mod ;
- break ;
- }
- need_to_show_score = TRUE ;
- }
- else {
- if( ( killer = find_player( input->killed_by_id ) ) > 0 ) {
- post_new_message( 0, no_sfx, "%s was killed by %s.",
- input->name, player[killer].name ) ;
- }
- else {
- post_new_message( 0, no_sfx, "%s is dead.", input->name ) ;
- }
- }
- }
-
- /*
- * If player's missile is transitioning from active to exploding...
- */
- if( input->msl_status < 0 && player[number].msl_status > 0 ) {
- explosion_sfx( input->msl_x - player[SELF].x,
- input->msl_y - player[SELF].y,
- player[SELF].head ) ;
- }
-
- /*
- * If player is transitioning from having a flag to dropping one...
- */
- if( !HAS_A_FLAG( *input ) && HAS_A_FLAG( player[number] ) ) {
- player_dropped_flag( input ) ;
- }
-
- /*
- * If player is transitioning from not having a flag to having one...
- */
- else if( HAS_A_FLAG( *input ) && !HAS_A_FLAG( player[number] ) ) {
- set_bulletin_color( teamColor[player[SELF].team] ) ;
- post_new_message( 0, 1, "%s grabbed %s flag.", player[number].name,
- HAS_RED_FLAG( *input ) ? "red" : "blue" ) ;
- if( input->team != player[SELF].team &&
- player[SELF].team != NEUTRAL_TEAM ) {
- sfx( SFX_FLAG_GRABBED ) ;
- }
- }
-
- /*
- * Update player.
- */
- copy_player( number, input ) ;
-
- #if !defined( NETDEBUGGER )
- /*
- * If player has hit me, blow up.
- */
- if( input->hit_by_id == player[SELF].id && hit_by[number] == 0
- && IS_ALIVE( player[SELF] ) ) {
- blow_up_self( number ) ;
- }
- #endif /* !defined( NETDEBUGGER ) */
- }
-
-
-
- static void process_bz_notice(
- struct BzNotice *input,
- int team
- )
- {
- #if !defined( NETDEBUGGER )
- int number ;
-
- if( valid_host( input->id ) && ( number = find_player( input->id ) ) > 0 ) {
- switch( team ) {
- case NEUTRAL_TEAM :
- post_new_message( 0, 0, "From %s:", player[number].name ) ;
- post_new_message( 0, 1, ">%s", input->out_message ) ;
- break ;
-
- case RED_TEAM :
- if( player[SELF].team == team ) {
- set_bulletin_color( teamColor[RED_TEAM] ) ;
- post_new_message( 0, 0, "From %s to RED team:",
- player[number].name ) ;
- set_bulletin_color( teamColor[RED_TEAM] ) ;
- post_new_message( 0, 1, ">%s", input->out_message ) ;
- }
- break ;
-
- case BLUE_TEAM :
- if( player[SELF].team == team ) {
- set_bulletin_color( teamColor[BLUE_TEAM] ) ;
- post_new_message( 0, 0, "From %s to BLUE team:",
- player[number].name ) ;
- set_bulletin_color( teamColor[BLUE_TEAM] ) ;
- post_new_message( 0, 1, ">%s", input->out_message ) ;
- }
- break ;
- }
-
- if( write_packets == file_out ) {
- if( write( out_fd, (void *)input, sizeof(struct BzMember) )
- < sizeof(struct BzMember) ) {
- perror( "process_bz_notice" ) ;
- end_program( 0 ) ;
- }
- }
- }
- #endif /* !defined( NETDEBUGGER ) */
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Handle flag droppings...
- *----------------------------------------------------------------------------*/
- static void player_dropped_flag(
- struct BzMember *fumbler
- )
- {
- int his_team ;
- int other_team ;
- int his_flag ;
- int other_flag ;
- int killer ;
- float his_flag_home_x ;
- float his_flag_home_y ;
- float other_flag_home_x ;
- float other_flag_home_y ;
- Boolean his_flag_held ;
-
- his_team = fumbler->team ;
-
- if( player[SELF].id == fumbler->id )
- need_to_show_flag_st = TRUE ;
-
- /*
- * Initialize his team/other team indicators.
- */
- switch( his_team ) {
-
- case RED_TEAM :
- other_team = BLUE_TEAM ;
- his_flag_home_x = RED_FLAG_HOME_X ;
- his_flag_home_y = RED_FLAG_HOME_Y ;
- other_flag_home_x = BLUE_FLAG_HOME_X ;
- other_flag_home_y = BLUE_FLAG_HOME_Y ;
- his_flag = RED_FLAG ;
- other_flag = BLUE_FLAG ;
- his_flag_held = red_flag_held ;
- break ;
-
- case BLUE_TEAM :
- other_team = RED_TEAM ;
- his_flag_home_x = BLUE_FLAG_HOME_X ;
- his_flag_home_y = BLUE_FLAG_HOME_Y ;
- other_flag_home_x = RED_FLAG_HOME_X ;
- other_flag_home_y = RED_FLAG_HOME_Y ;
- his_flag = BLUE_FLAG ;
- other_flag = RED_FLAG ;
- his_flag_held = blue_flag_held ;
- break ;
-
- default :
- return ;
-
- }
-
- /*
- * If dropped flag due to reset, reset it and signal.
- */
- if( LOST_FLAG( *fumbler ) ) {
- flag_x[other_flag] = other_flag_home_x ;
- flag_y[other_flag] = other_flag_home_y ;
- set_bulletin_color( teamColor[other_team] ) ;
- post_new_message( 0, 1, "%s flag was reset.", teamName[other_team] ) ;
- }
- else {
- set_bulletin_color( teamColor[other_team] ) ;
- post_new_message( 0, 1, "%s flag was dropped by %s.",
- teamName[other_team], fumbler->name ) ;
- if( IS_ALIVE( *fumbler ) ) {
- flag_x[other_flag] = fumbler->x ;
- flag_y[other_flag] = fumbler->y ;
- /*
- * Check if flag was dropped in home zone for capture.
- */
- if( his_flag_home_x - FLAG_HOME_PERIM < flag_x[other_flag] &&
- his_flag_home_x + FLAG_HOME_PERIM > flag_x[other_flag] &&
- his_flag_home_y - FLAG_HOME_PERIM < flag_y[other_flag] &&
- his_flag_home_y + FLAG_HOME_PERIM > flag_y[other_flag] ) {
- teamBonus[other_team] -= FLAG_BONUS ;
- teamBonus[his_team] += FLAG_BONUS ;
- /*
- * If on the same team, signal bonus.
- */
- if( player[SELF].team == his_team ) {
- set_bulletin_color( teamColor[his_team] ) ;
- post_new_message( 0, 1, "Team bonus for flag capture "
- "by %s.", fumbler->name ) ;
- sfx( SFX_FLAG_WON ) ;
- /*
- * Personal bonus if I dropped the flag.
- */
- if( player[SELF].id == fumbler->id ) {
- switch( player[SELF].tank_type ) {
- case 0:
- player[SELF].score += PERSONAL_BONUS - 50 ;
- break ;
- case 1:
- player[SELF].score += PERSONAL_BONUS - 75 ;
- break ;
- case 2:
- player[SELF].score += PERSONAL_BONUS - 100 ;
- break ;
- case 3:
- player[SELF].score += PERSONAL_BONUS - 125 ;
- break ;
- }
- need_to_show_score = TRUE ;
- }
- }
- /*
- * If on the other team and have his flag, lose it, and signal
- * that it has been reset.
- */
- else if( player[SELF].team == other_team ) {
- set_bulletin_color( teamColor[other_team] ) ;
- post_new_message( 0, 1, "Team penalty for flag capture "
- "by %s.", fumbler->name ) ;
- sfx( SFX_FLAG_LOST ) ;
- if( HAS_A_FLAG( player[SELF] ) ) {
- set_bulletin_color( teamColor[other_team] ) ;
- post_new_message( 0, 0, "%s flag was reset.",
- teamName[his_team] ) ;
- player[SELF].team_flag = RESET_FLAG_BIT ;
- flag_x[his_flag] = his_flag_home_x ;
- flag_y[his_flag] = his_flag_home_y ;
- }
- }
- flag_x[other_flag] = other_flag_home_x ;
- flag_y[other_flag] = other_flag_home_y ;
- /*
- * If his flag isn't held, go ahead and reset it. (If it
- * is held, wait for "holder" to signal that they lost it.)
- */
- if( !his_flag_held ) {
- flag_x[his_flag] = his_flag_home_x ;
- flag_y[his_flag] = his_flag_home_y ;
- set_bulletin_color( teamColor[his_team] ) ;
- post_new_message( 0, 0, "%s flag was reset.",
- teamName[his_team] ) ;
- }
- }
- }
- /*
- * Player dropped the flag due to death. Reset flag.
- */
- else {
- flag_x[other_flag] = other_flag_home_x ;
- flag_y[other_flag] = other_flag_home_y ;
- teamBonus[other_team] += FLAG_BONUS ;
- if( player[SELF].team == other_team ) {
- set_bulletin_color( teamColor[other_team] ) ;
- if( ( killer = find_player( fumbler->killed_by_id ) ) > 0 ) {
- post_new_message( 0, 1, "Team bonus for flag defense "
- "by %s.", player[killer].name ) ;
- }
- else {
- post_new_message( 0, 1, "Team bonus for flag defense." ) ;
- }
- }
- }
- }
- }
-
-
-
- void network_out( void )
- {
- int no_chars_sent ;
-
- no_chars_sent = sendto( out_fd, (char *)(&player[SELF]),
- sizeof(struct BzMember), 0, &out_addr,
- out_addrlen ) ;
- if( no_chars_sent < sizeof(struct BzMember) ) {
- perror( "network_out" ) ;
- end_program( 0 ) ;
- }
-
- if( !never_have_flag ) {
- check_to_send_census() ;
- }
- }
-
-
-
- void send_out(
- void *buf,
- int size
- )
- {
- #if !defined( NETDEBUGGER )
- if( write_packets == network_out ) {
- send_to_network( buf, size ) ;
- }
- else if( write_packets == file_out ) {
- send_to_file( buf, size ) ;
- }
- #else
- write( 1, buf, size ) ;
- #endif /* !defined( NETDEBUGGER ) */
- }
-
-
-
- void send_to_file(
- void *buf,
- int size
- )
- {
- int no_chars_sent ;
-
- no_chars_sent = write( out_fd, buf, size ) ;
- if( no_chars_sent < size ) {
- perror( "send_to_file" ) ;
- end_program( 0 ) ;
- }
- }
-
-
-
- void send_to_network(
- char *buf,
- int size
- )
- {
- int no_chars_sent ;
-
- no_chars_sent = sendto( out_fd, buf, size, 0, &out_addr, out_addrlen ) ;
- if( no_chars_sent < size ) {
- perror( "send_to_network" ) ;
- end_program( 0 ) ;
- }
- }
-
-
-
- void network_in( void )
- {
- int no_chars_received ;
- union BzPacket packet ;
- struct BzAck ack ;
- int st = 0 ;
- int number ;
- int socket_empty = 0 ;
- static int newer = 0 ;
-
- while( !socket_empty ) {
- no_chars_received = recvfrom( in_fd, (char *)(&packet),
- sizeof(union BzPacket), 0, &in_addr,
- &in_addrlen ) ;
- if( no_chars_received < 0 && errno == EWOULDBLOCK ) {
- socket_empty = 1 ;
- }
- else {
- switch( packet.bz_id ) {
- case BZ :
- if( no_chars_received == sizeof( struct BzMember ) ) {
- if( view_only || valid_host( packet.member.id ) ) {
- process_bz_packet( &(packet.member) ) ;
- }
- else if ( view_only ) {
- if( valid_keyed_host( packet.ack.id,
- packet.ack.key ) ) {
- process_bz_packet( &(packet.member) ) ;
- }
- }
- /*
- * New player, send out acknowledge packet.
- */
- else if( number_players < MAXPLAYERS &&
- should_acknowledge( packet.member.id,
- packet.member.key ) ) {
- send_acknowledgement( packet.member.id ) ;
- }
- }
- else {
- st = sizeof( struct BzMember ) ;
- }
- break ;
-
- case BZMSG :
- if( no_chars_received == sizeof( struct BzNotice ) ) {
- process_bz_notice( &(packet.notice), NEUTRAL_TEAM ) ;
- }
- else {
- st = sizeof( struct BzNotice ) ;
- }
- break ;
-
- case BZREDMSG :
- if( no_chars_received == sizeof( struct BzNotice ) ) {
- process_bz_notice( &(packet.notice), RED_TEAM ) ;
- }
- else {
- st = sizeof( struct BzNotice ) ;
- }
- break ;
-
- case BZBLUEMSG :
- if( no_chars_received == sizeof( struct BzNotice ) ) {
- process_bz_notice( &(packet.notice), BLUE_TEAM ) ;
- }
- else {
- st = sizeof( struct BzNotice ) ;
- }
- break ;
-
- case BZLOGO_00 :
- if( no_chars_received == sizeof( packet.logo ) ) {
- if( ( number = find_player( packet.logo.id ) ) > 0 &&
- tank_logo[number] == null_obj ) {
- tank_logo[number] =
- create_logo( packet.logo.logo_info, 1,
- &(tank_logo_side[number]) ) ;
- }
- }
- break ;
-
- case BZQUIT :
- if( no_chars_received == sizeof( struct BzAck ) ) {
- if( ( number = find_player( packet.ack.id ) ) > 0 ) {
- remove_host( packet.ack.id ) ;
- delete_player( number, "quit" ) ;
- }
- /*
- * Trial stuff.
- */
- else {
- quit_host( packet.ack.id ) ;
- }
- }
- break ;
-
- case BZACK :
- if( no_chars_received == sizeof( struct BzAck ) ) {
- /*
- * If acknowledging SELF, add to list of valid hosts.
- */
- if( packet.ack.ack_id == player[SELF].id ) {
- valid_keyed_host( packet.ack.id, packet.ack.key ) ;
- }
- }
- else {
- st = sizeof( struct BzAck ) ;
- }
- break ;
-
- case BZDROP :
- if( no_chars_received == sizeof( struct BzAck ) ) {
- /*
- * If dropping SELF, note dropped status with host.
- */
- if( packet.ack.ack_id == player[SELF].id &&
- valid_host( packet.ack.id ) ) {
- dropped_by_host( packet.ack.id ) ;
- if( ( number = find_player( packet.ack.id ) ) > 0 ){
- delete_player( number, "was dropped" ) ;
- }
- }
- }
- else {
- st = sizeof( struct BzAck ) ;
- }
- break ;
-
- case BZINVALIDATE :
- if( no_chars_received == sizeof( struct BzAck ) ) {
- /*
- * If invalidating SELF, invalidate in kind.
- */
- if( packet.ack.ack_id == player[SELF].id &&
- valid_host( packet.ack.id ) ) {
- dprintf( "%s: received invalidate packet from %s\n",
- print_time(),
- host_name_from_id( packet.ack.id ) ) ;
- invalidate_host( packet.ack.id ) ;
- if( ( number = find_player( packet.ack.id ) ) > 0 ){
- delete_player( number, "was dropped" ) ;
- }
- }
- }
- else {
- st = sizeof( struct BzAck ) ;
- }
- break ;
-
- case BZCENSUS :
- if( no_chars_received == sizeof( struct BzCensus ) ) {
- if( valid_host( packet.census.id ) ) {
- process_bz_census( &(packet.census) ) ;
- }
- }
- else {
- st = sizeof( struct BzCensus ) ;
- }
- break ;
-
- default :
- if( packet.bz_id > BZ &&
- ( packet.bz_id & 0xffffff00 ) == (BZ & 0xffffff00) &&
- newer == 0 ) {
- newer = 1 ;
- printf( "\n\nAn newer version of %s is being played on "
- "the net.\n\n", basename ) ;
- }
- break ;
- }
- if( st ) {
- fprintf( stderr, "received odd packet size of %d instead of "
- "%d! (id = 0x%08x)\n", no_chars_received, st,
- packet.bz_id ) ;
- st = 0 ;
- }
- }
- }
-
- process_players() ;
- }
-
-
-
- void blow_up_self(
- int killer
- )
- {
- if( !view_only ) {
- if( killer < 0 ) {
- post_new_message( 0, no_sfx, "Vaporized by force field." ) ;
- player[SELF].killed_by_id = 0 ;
- }
- else {
- post_new_message( 0, no_sfx, "%s by %s.",
- ( player[killer].hit_type == HIT_BY_MISSILE ) ? "Killed" :
- "Mined", player[killer].name ) ;
- player[SELF].killed_by_id = killer ;
- hit_by[killer] = MAX_HIT_BY_COUNT ;
- }
-
-
- sfx( SFX_EXPLOSION ) ;
-
- guiding = FALSE ;
- reset_mouse() ;
- player[SELF].status = MAX_DEAD_STATUS ;
- copy_time( &time_of_death, ¤t_time ) ;
-
- if( !solo ) {
- switch( player[SELF].tank_type ) {
- case 0:
- player[SELF].score -= 50 ;
- break ;
- case 1:
- player[SELF].score -= 75 ;
- break ;
- case 2:
- player[SELF].score -= 100 ;
- break ;
- case 3:
- player[SELF].score -= 125 ;
- break ;
- }
- }
-
- need_to_show_score = TRUE ;
- left_track = right_track = 0.0f ;
- vx[SELF] = vy[SELF] = 0.0f ;
- loading_missile = 0 ;
-
- if( HAS_A_FLAG( player[SELF] ) ) {
- player_dropped_flag( &player[SELF] ) ;
- player[SELF].team_flag = 0 ;
- }
-
- if( sending_msg == SENDING_NO_MAIL ) {
- ol_mode = 1 ;
- setTranslations( deadTransTable ) ;
- }
- else {
- ol_mode = 0 ;
- setTranslations( deadMailTransTable ) ;
- }
- GLXwinset( display, radar_ol_window ) ;
- drawOverlay() ;
- GLXwinset( display, base_window ) ;
- }
- }
-
-
-
- int find_player(
- long id
- )
- {
- int i ;
- int found ;
-
- found = 0 ;
- i = 1 ;
- while( i < number_players && !found ) {
- if( player[i].id == id ) found = i ;
- i++ ;
- }
-
- return(found);
- }
-
-
-
- void add_player( int *number )
- {
- if( number_players <= MAXPLAYERS ) {
- *number = number_players ;
- number_players++ ;
- tank_logo[*number] = null_obj ;
- need_to_show_players = TRUE ;
- }
- else {
- printf( "Maximum number (%d) of players exceeded.\n", MAXPLAYERS ) ;
- end_program(0);
- }
- }
-
-
-
- void delete_player(
- int i,
- char *verb
- )
- {
- int j ;
-
- post_new_message( 0, 1, "%s %s.", player[i].name, verb ) ;
-
- if( networking && !view_only ) {
- remove_host_from_census( player[i].id ) ;
- dprintf( "%s: %s %s.\n", print_time(),
- host_name_from_id( player[i].id ), verb ) ;
- }
-
- for( j = i ; j < number_players-1 ; j++ ) {
- copy_player( j, &(player[j+1]) ) ;
- tank_logo[j] = tank_logo[j+1] ;
- activity[j] = activity[j+1] ;
- hit_by[j] = hit_by[j+1] ;
- bcopy( &(deadline[j+1]), &(deadline[j]), sizeof( deadline[j] ) ) ;
- }
-
- reset_viewing_order() ;
-
- number_players-- ;
- hit_by[number_players] = 0 ;
- activity[number_players] = 0 ;
- tank_logo[number_players] = null_obj ;
- need_to_show_players = TRUE ;
- #if defined( NETDEBUGGER )
- show_player_list() ;
- #endif /* defined( NETDEBUGGER ) */
-
- if( view_only && show_copilot_view ) {
- if( number_players == 1 ) {
- show_copilot_view = FALSE ;
- }
- else if( copilot_player == i ) {
- next_copilot_view() ;
- }
- else if( copilot_player > i ) {
- copilot_player-- ;
- }
- }
- }
-
-
-
- void copy_player(
- int k,
- struct BzMember *psrc
- )
- {
- bcopy( psrc, &(player[k]), sizeof( struct BzMember ) ) ;
- }
-
-
-
- void check_name( void )
- {
- char temp[NAMELEN] ;
- unsigned i ;
- unsigned duplicate = 0 ;
-
- for( i = ENEMY ; i < number_players ; i++ ) {
- if( !strcmp( player[SELF].name, player[i].name ) ) duplicate = 1 ;
- }
-
- if( duplicate ) {
- cuserid( temp ) ;
- if( strncmp( player[SELF].name, temp, NAMELEN-1 ) == 0 ) {
- i = strlen( player[SELF].name ) ;
- if( i < NAMELEN - 3 ) {
- player[SELF].name[i ] = '_' ;
- player[SELF].name[i+1] = 'a' + ( rand() % 26 ) ;
- player[SELF].name[i+2] = '\0' ;
- }
- else if( i < NAMELEN - 2 ) {
- player[SELF].name[i ] = 'a' + ( rand() % 26 ) ;
- player[SELF].name[i+1] = '\0' ;
- }
- else {
- player[SELF].name[NAMELEN-2] = 'a' + ( rand() % 26 ) ;
- }
- }
- else {
- strncpy( player[SELF].name, temp, NAMELEN );
- }
- player[SELF].name[NAMELEN-1] = '\0' ;
- post_new_message( 0, 1, "Modified name to `%s'.", player[SELF].name ) ;
- name_count = 0 ;
- }
- }
-
-
-
- void check_id(
- int n
- )
- {
- struct in_addr addr ;
- struct hostent *hp ;
-
- if( player[n].id == player[SELF].id ) {
- addr.s_addr = player[n].id ;
- hp = gethostbyaddr( &addr, sizeof(addr), AF_INET ) ;
- fprintf( stderr, "\n%s@%s is using your host id!\n\n", player[n].name,
- hp ? hp->h_name : inet_ntoa(addr) ) ;
- end_program( 1 ) ;
- }
- }
-
-
- void file_name( char *name )
- {
- char temp[NAMELEN] ;
- unsigned i ;
- unsigned l ;
-
- cuserid( temp ) ;
- l = strlen( temp );
- name[ 0] = '/' ;
- name[ 1] = 't' ;
- name[ 2] = 'm' ;
- name[ 3] = 'p' ;
- name[ 4] = '/' ;
- name[ 5] = '.' ;
- name[ 6] = 'T' ;
- name[ 7] = 'M' ;
- name[ 8] = 'P' ;
- name[ 9] = 'a' ;
- name[10] = '0' ;
- name[11] = '0' ;
- name[12] = '0' ;
- name[13] = '0' ;
- name[14] = '0' ;
- name[15] = '\0';
- for( i = 0 ; i < l ; i++ )
- name[10+i] = (char)('0' + temp[i] % 10) ;
- }
-
-
-
- void check_quit_time( void )
- {
- FILE *f ;
- long clock_old, clock_new ;
-
- player[SELF].score = 0 ;
- file_name( time_name );
- if( ( f = fopen( time_name, "r" ) ) != NULL ) {
- if( fscanf( f, "%ld\n", &clock_old ) == 1 ) {
- time( &clock_new ) ;
- if( (clock_new - clock_old) < 120 ) {
- fscanf( f, "%d", &(player[SELF].score) ) ;
- if( player[SELF].score > 0 )
- player[SELF].score = 0 ;
- else
- player[SELF].score -= 100 ;
- }
- }
- fclose(f);
- }
- }
-
-
-
- void set_quit_time( void )
- {
- FILE *f ;
- long clock_new ;
-
- file_name( time_name );
- if( ( f = fopen( time_name, "w" ) ) != NULL ) {
- time( &clock_new ) ;
- fprintf( f, "%ld\n", clock_new ) ;
- fprintf( f, "%d", player[SELF].score ) ;
- fclose(f);
- }
- }
-
-
-
- void send_out_message( void )
- {
- int no_chars_sent ;
- char sombuf[80] ;
- Colorindex c ;
-
- switch( sending_msg ) {
- case SENDING_ALL_MAIL :
- mail.bz_id = BZMSG ;
- mail.id = player[SELF].id ;
- sombuf[0] = '\0' ;
- c = green ;
- break ;
- case SENDING_TEAM_MAIL :
- switch( player[SELF].team ) {
- default :
- case NEUTRAL_TEAM :
- mail.bz_id = BZMSG ;
- mail.id = player[SELF].id ;
- sombuf[0] = '\0' ;
- c = teamColor[NEUTRAL_TEAM] ;
- break ;
- case RED_TEAM :
- mail.bz_id = BZREDMSG ;
- mail.id = player[SELF].id ;
- strcpy( sombuf, " to RED team" ) ;
- c = teamColor[RED_TEAM] ;
- break ;
- case BLUE_TEAM :
- mail.bz_id = BZBLUEMSG ;
- mail.id = player[SELF].id ;
- strcpy( sombuf, " to BLUE team" ) ;
- c = teamColor[BLUE_TEAM] ;
- break ;
- }
- break ;
- default :
- return ;
- }
- set_bulletin_color( c ) ;
- post_new_message( 0, 0, "Broadcast%s:", sombuf ) ;
- set_bulletin_color( c ) ;
- post_new_message( 0, 1, ">%s", mail.out_message ) ;
- if( write_packets == network_out ) {
- send_to_network( (char *)&mail, sizeof( mail ) ) ;
- no_chars_sent = sizeof(struct BzMember) ;
- }
- else if( write_packets == file_out ) {
- no_chars_sent = write( out_fd, (void *)&mail, sizeof(struct BzMember) );
- }
- else {
- no_chars_sent = sizeof(struct BzMember) ;
- }
- if( no_chars_sent < sizeof(struct BzMember) ) {
- perror( "send_out_message" ) ;
- end_program( 0 ) ;
- }
- }
-
-
-
- static void tran_rot_show(
- float x,
- float y,
- float heading,
- GL_Object obj
- )
- {
- if( obj != null_obj ) {
- pushmatrix() ;
- translate( x, y, 0.f ) ;
- rot( -heading, 'z' ) ;
- callobj( obj ) ;
- popmatrix() ;
- }
- }
-
-
-
- static void input_message(
- int init
- )
- {
- char *s ;
- unsigned add_char = 0 ;
- static int nochars = 0 ;
-
- if( init ) {
- nochars = 0 ;
- mail.out_message[nochars] = '\0' ;
- add_char = 1 ;
- }
-
- s = mail_buffer ;
- while( mail_ptr ) {
- if( *s == '\r' ) {
- if( nochars > 0 ) {
- send_out_message() ;
- }
- sending_msg = SENDING_NO_MAIL ;
- mail.out_message[0] = '\0' ;
- ol_mode = 1 ;
- if( IS_ALIVE( player[SELF] ) ) {
- setTranslations( mainTransTable ) ;
- }
- else {
- setTranslations( deadTransTable ) ;
- GLXwinset( display, radar_ol_window ) ;
- drawOverlay() ;
- GLXwinset( display, base_window ) ;
- }
- nochars = 0 ;
- mail.out_message[nochars] = '\0' ;
- }
- else if( *s == '\010' ) {
- nochars -= ( nochars > 0 ) ? 1 : 0 ;
- mail.out_message[nochars] = '\0' ;
- }
- else if( nochars < MAIL_MSG_SIZE ) {
- mail.out_message[nochars++] = *s ;
- mail.out_message[nochars] = '\0' ;
- }
- s++ ;
- mail_ptr-- ;
- add_char = 1 ;
- }
- if( add_char ) {
- need_to_show_out_message = TRUE ;
- }
- }
-
-
-
- static void usage( void )
- {
- fprintf( stderr, "Usage:\n\n" ) ;
- fprintf( stderr, "\t%s [-n name] [-i infile] [-o outfile] [-T ttl]"
- " [-red | -blue | -pick]\n", basename );
- fprintf( stderr, "\t [-noflag] [-public | -private key]"
- " [-logo logofile] [-vo] [-fast]\n\n" ) ;
- fprintf( stderr, "\t%s -solo [-practice level] [-kids] [-n name]"
- " [-logo logofile] [-fast]\n\n", basename ) ;
- fprintf( stderr, "\t%s -version\n\n", basename ) ;
- end_program( 1 ) ;
- }
-
-
-
- static void move_args(
- int argc,
- char **argv,
- int start,
- int n
- )
- {
- int i ;
- char *t ;
-
- while( n-- ) {
- t = argv[start] ;
- for( i = start ; i < argc - 1 ; i++ ) {
- argv[i] = argv[i+1] ;
- }
- argv[argc-1] = t ;
- }
- }
-
-
-
- static void parse_args(
- int *argc,
- char **argv
- )
- {
- int i ;
- int key ;
- int argn = 0 ;
-
- if( ( basename = strrchr( argv[0], '/' ) ) == NULL )
- basename = argv[0] ;
- else
- basename++ ;
-
- for( i = 1 ; i < *argc ; i++ ) {
- argn++ ;
- if( argv[i][0] == '-' ) {
- if( !strcmp( argv[i]+1, "n" ) ) {
- if( i + 1 == *argc ) {
- usage() ;
- }
- else {
- strncpy( player_name, argv[i+1], NAMELEN ) ;
- player_name[NAMELEN-1] = '\0' ;
- move_args( *argc, argv, i, 2 ) ;
- *argc -= 2 ;
- i-- ;
- }
- }
- else if( !strcmp( argv[i]+1, "logo" ) ) {
- if( i + 1 == *argc ) {
- usage() ;
- }
- else {
- logo_file = argv[i+1] ;
- move_args( *argc, argv, i, 2 ) ;
- *argc -= 2 ;
- i-- ;
- }
- }
- else if( !strcmp( argv[i]+1, "i" ) ) {
- if( solo || i + 1 == *argc ) {
- usage() ;
- }
- else {
- in_name = argv[i+1] ;
- move_args( *argc, argv, i, 2 ) ;
- *argc -= 2 ;
- i-- ;
- networking = FALSE ;
- }
- }
- else if( !strcmp( argv[i]+1, "o" ) ) {
- if( solo || i + 1 == *argc ) {
- usage() ;
- }
- else {
- out_name = argv[i+1] ;
- move_args( *argc, argv, i, 2 ) ;
- *argc -= 2 ;
- i-- ;
- networking = FALSE ;
- }
- }
- else if( !strcmp( argv[i]+1, "T" ) ) {
- if( solo || i + 1 == *argc ) {
- usage() ;
- }
- else {
- timeToLive = atoi( argv[i+1] ) ;
- move_args( *argc, argv, i, 2 ) ;
- *argc -= 2 ;
- i-- ;
- }
- }
- else if( !strcmp( argv[i]+1, "public" ) ) {
- if( solo || i + 1 == *argc ) {
- usage() ;
- }
- else if( ( game_key & GAME_KEY_MASK ) == 0 ) {
- key = (unsigned short)atoi( argv[i+1] ) ;
- if( key > GAME_KEY_MASK ) {
- fprintf( stderr, "%s: public game key must be between "
- "0 and %d\n", basename, GAME_KEY_MASK ) ;
- end_program( 1 ) ;
- }
- game_key |= key ;
- move_args( *argc, argv, i, 2 ) ;
- *argc -= 2 ;
- i-- ;
- }
- else {
- usage() ;
- }
- }
- else if( !strcmp( argv[i]+1, "private" ) ) {
- if( solo || i + 1 == *argc ) {
- usage() ;
- }
- else if( ( game_key & GAME_KEY_MASK ) == 0 ) {
- key = (unsigned short)atoi( argv[i+1] ) ;
- if( key > GAME_KEY_MASK ) {
- fprintf( stderr, "%s: private game key must be between"
- " 0 and %d\n", basename, GAME_KEY_MASK ) ;
- end_program( 1 ) ;
- }
- game_key |= PRIVATE_GAME | key ;
- move_args( *argc, argv, i, 2 ) ;
- *argc -= 2 ;
- i-- ;
- }
- else {
- usage() ;
- }
- }
- else if( !strcmp( argv[i]+1, "noflag" ) ) {
- if( solo ) {
- usage() ;
- }
- else {
- never_have_flag = TRUE ;
- move_args( *argc, argv, i, 1 ) ;
- *argc -= 1 ;
- i-- ;
- }
- }
- else if( !strcmp( argv[i]+1, "fast" ) ) {
- game_key |= FAST_GAME ;
- move_args( *argc, argv, i, 1 ) ;
- *argc -= 1 ;
- i-- ;
- }
- else if( !strcmp( argv[i]+1, "vo" ) ) {
- if( solo ) {
- usage() ;
- }
- else {
- view_only = TRUE ;
- move_args( *argc, argv, i, 1 ) ;
- *argc -= 1 ;
- i-- ;
- }
- }
- else if( !strcmp( argv[i]+1, "red" ) ) {
- if( !solo && player[SELF].team == NEUTRAL_TEAM &&
- !pick_my_team ) {
- player[SELF].team = RED_TEAM ;
- red_team_present = TRUE ;
- move_args( *argc, argv, i, 1 ) ;
- *argc -= 1 ;
- i-- ;
- }
- else {
- usage() ;
- }
- }
- else if( !strcmp( argv[i]+1, "blue" ) ) {
- if( !solo && player[SELF].team == NEUTRAL_TEAM &&
- !pick_my_team ) {
- player[SELF].team = BLUE_TEAM ;
- blue_team_present = TRUE ;
- move_args( *argc, argv, i, 1 ) ;
- *argc -= 1 ;
- i-- ;
- }
- else {
- usage() ;
- }
- }
- else if( !strcmp( argv[i]+1, "pick" ) ) {
- if( !solo && player[SELF].team == NEUTRAL_TEAM &&
- !pick_my_team ) {
- pick_my_team = TRUE ;
- move_args( *argc, argv, i, 1 ) ;
- *argc -= 1 ;
- i-- ;
- }
- else {
- usage() ;
- }
- }
- else if( !strcmp( argv[i]+1, "solo" ) ) {
- if( argn == 1 ) {
- solo = TRUE ;
- networking = FALSE ;
- move_args( *argc, argv, i, 1 ) ;
- *argc -= 1 ;
- i-- ;
- }
- else {
- usage() ;
- }
- }
- else if( !strcmp( argv[i]+1, "kids" ) ) {
- if( solo ) {
- kids_mode = TRUE ;
- move_args( *argc, argv, i, 1 ) ;
- *argc -= 1 ;
- i-- ;
- }
- else {
- usage() ;
- }
- }
- else if( !strcmp( argv[i]+1, "practice" ) ) {
- if( !solo || i + 1 == *argc || practice_level != 0 ) {
- usage() ;
- }
- else {
- practice_level = atoi( argv[i+1] ) ;
- if( practice_level < 1 ) {
- fprintf( stderr, "%s: practice level must be greater "
- "than 0\n", basename ) ;
- end_program( 1 ) ;
- }
- else if( practice_level > 999 ) {
- practice_level = 999 ;
- }
- move_args( *argc, argv, i, 2 ) ;
- *argc -= 2 ;
- i-- ;
- }
- }
- else if( !strcmp( argv[i]+1, "version" ) ) {
- fprintf( stderr, "%s version %s\n", basename,
- print_version() ) ;
- exit( 0 ) ;
- }
- }
- }
-
- if( view_only && player[SELF].team != NEUTRAL_TEAM ) {
- fprintf( stderr, "%s: can not be a team member in view-only mode.\n",
- basename ) ;
- player[SELF].team = NEUTRAL_TEAM ;
- }
- }
-
-
-
- static void basic_initialization(
- int *argc,
- char **argv
- )
- {
- int i ;
- int k ;
-
- start_time( &start_up_time ) ;
- number_players = 1 ;
-
- player[SELF].team = NEUTRAL_TEAM ;
- parse_args( argc, argv ) ;
-
- if( never_have_flag ) {
- game_key |= NO_FLAG_GAME ;
- }
-
- if( game_key & FAST_GAME ) {
- for( i = 0 ; i < sizeof( vmax ) / sizeof( vmax[0] ) ; i++ ) {
- vmax[i] *= FAST_FACTOR ;
- }
- gm_vel *= FAST_FACTOR ;
- rm_vel *= FAST_FACTOR ;
- t_factor = FAST_FACTOR * DHEAD / vmax[2] / 6.f ;
- }
- else {
- t_factor = DHEAD / vmax[2] / 2.f ;
- }
-
- register_key( game_key ) ;
-
- #if !defined( NETDEBUGGER )
- get_screen_dimensions() ;
- set_up_screen_dimensions() ;
-
- if( getgdesc( GD_BITS_OVER_SNG_CMODE ) < 2 )
- use_pups = TRUE ;
- #endif /* !defined( NETDEBUGGER ) */
-
- player[SELF].name[NAMELEN-1] = '\0' ;
- for( i = strlen(player[SELF].name)-1; i > 0 && player[SELF].name[i] == ' ' ;
- i++ ) {
- player[SELF].name[i] = '\0' ;
- }
-
- player[SELF].key = game_key ;
- player[SELF].team_flag = 0 ;
-
- if( solo ) {
- lives = 3 ;
- deadTranslations = soloDeadTranslations ;
- }
- else {
- lives = 1 ;
- deadTranslations = netDeadTranslations ;
- }
- level = practice_level ;
-
- if( view_only ) {
- mainTranslations = viewonlyTranslations ;
- }
- else {
- mainTranslations = netMainTranslations ;
- }
-
- if( networking && !view_only && !solo )
- check_quit_time();
-
- if( view_only || !networking ) {
- dprintf( "disable" ) ;
- }
- else {
- dprintf( "%s: starting game version %s (%s)\n", print_time(),
- print_version(), print_date() ) ;
- }
-
- #if !defined( NETDEBUGGER )
- if( networking || solo ) {
- player[SELF].id = gethostid() ;
- }
- else {
- player[SELF].id = 1 ;
- }
-
- k = 0 ;
- for( i = 0 ; i < 30 ; i++ ) {
- fracture[i].v0[0] = (float)fracdest[k++] ;
- fracture[i].v0[1] = (float)fracdest[k++] ;
- fracture[i].v1[0] = (float)fracdest[k++] ;
- fracture[i].v1[1] = (float)fracdest[k++] ;
- }
-
- no_sfx = init_sound() ;
-
- #endif /* !defined( NETDEBUGGER ) */
- }
-
-
-
- static void overlayExposeCB(
- Widget w,
- XtPointer client_data,
- XtPointer call_data
- )
- {
- GLXwinset( XtDisplay(w), ((GlxDrawCallbackStruct *)call_data)->window ) ;
- drawOverlay() ;
- GLXwinset( display, base_window ) ;
- }
-
-
-
- static void drawSceneCB(
- Widget w,
- XtPointer client_data,
- XtPointer call_data
- )
- {
- GLXwinset( XtDisplay(w), ((GlxDrawCallbackStruct *)call_data)->window ) ;
- redraw_main_view() ;
- GLXwinset( display, base_window ) ;
- }
-
-
-
- void indicate_map_order(
- Window w,
- int map
- )
- {
- map_window[map_counter] = w ;
- map_index[map_counter] = map ;
- map_counter++ ;
- }
-
-
-
- static void initGlCB(
- Widget w,
- XtPointer client_data,
- XtPointer call_data )
- {
- #if !defined( NETDEBUGGER )
- int n ;
- Dimension wi, hi ;
- Dimension x, y ;
- float a ;
-
- mainview_window = ((GlxDrawCallbackStruct *)call_data)->window ;
- GLXwinset( XtDisplay(w), mainview_window ) ;
-
- n = 0 ;
- XtSetArg( wargs[n], XmNwidth, &wi ) ; n++ ;
- XtSetArg( wargs[n], XmNheight, &hi ) ; n++ ;
- XtSetArg( wargs[n], XmNx, &x ) ; n++ ;
- XtSetArg( wargs[n], XmNy, &y ) ; n++ ;
- XtGetValues( w, wargs, n ) ;
-
- aspect_ratio = (float)wi / (float)hi ;
- min_cull_angle = 0.5f * 30.0f * aspect_ratio + 30.f ;
- max_cull_angle = 360.0f - min_cull_angle ;
-
- a = atan( aspect_ratio * tanf( 0.5f * 30.0f * DEG2RAD ) ) / DEG2RAD ;
- radar_view_angle[0][0] = -800.f * SINE( a ) ;
- radar_view_angle[0][1] = 800.f * COSINE( a ) ;
- radar_view_angle[2][0] = -radar_view_angle[0][0] ;
- radar_view_angle[2][1] = radar_view_angle[0][1] ;
-
- a = atan( aspect_ratio * tanf( 0.5f * 5.0f * DEG2RAD ) ) / DEG2RAD ;
- binocular_radar_view_angle[0][0] = -800.f * SINE( a ) ;
- binocular_radar_view_angle[0][1] = 800.f * COSINE( a ) ;
- binocular_radar_view_angle[2][0] = -binocular_radar_view_angle[0][0] ;
- binocular_radar_view_angle[2][1] = binocular_radar_view_angle[0][1] ;
-
- zbuffer( FALSE ) ;
- subpixel( TRUE ) ;
- mmode( MVIEWING ) ;
- loadmatrix( id_mat ) ;
- concave( FALSE ) ;
- backface( FALSE ) ;
- shademodel( FLAT ) ;
-
- init_color( MAIN_VIEW_MAP, w ) ;
- indicate_map_order( mainview_window, MAIN_VIEW_MAP ) ;
-
- mv_w = FVPMVIEW_R - FVPMVIEW_L ;
- mv_h = FVPMVIEW_T - FVPMVIEW_B ;
- mv_m = FVPGROND_T - FVPMVIEW_B ;
-
- make_mv_objects() ;
-
- tank_logo[0] = null_obj ;
- if( logo_file == NULL || strlen( logo_file ) == 0 ) {
- logo_file = AppRes.logoFile ;
- }
-
- if( logo_file != NULL && strlen( logo_file ) > 0 ) {
- if( ( tank_logo[0] = read_logo( logo_file, logo_packet.logo_info,
- LOGO_SIZE, 0, &n ) ) == 0 ) {
- tank_logo[0] = null_obj ;
- }
- }
-
- init_lighting() ;
-
- loadmatrix( id_mat ) ;
- perspective( 300, aspect_ratio, .5f, 10000.f ) ;
- rotate( -900, 'x' ) ;
- bind_lighting() ;
- #else
- tank_logo[SELF] = null_obj ;
- #endif /* !defined( NETDEBUGGER ) */
- }
-
-
-
- static void changeVolume(
- Widget w,
- XEvent *event,
- String *params,
- Cardinal *numParams
- )
- {
- int selection ;
-
- if( !no_sfx ) {
- if( *numParams == 0 ) {
- selection = 0 ;
- }
- else {
- selection = atoi( params[0] ) ;
- }
-
- post_new_message( 0, 0, "Volume set to %d.",
- volume_change( selection ) ) ;
- }
- }
-
-
-
- static void tankSelect(
- Widget w,
- XEvent *event,
- String *params,
- Cardinal *numParams
- )
- {
- int selection ;
-
- if( *numParams == 0 ) {
- selection = '1' ;
- }
- else {
- selection = params[0][0] ;
- }
-
- GLXwinset( display, base_window ) ;
- choose_tank( selection ) ;
-
- if( init_wait ) {
- setTranslations( mainTransTable ) ;
- start_time( ¤t_time ) ;
- init_census_packet( player[SELF].id ) ;
- reset_mouse() ;
- reinterpret_mouse() ;
- ol_mode = 0 ;
- place_self();
- init_wait = 0 ;
- if( solo ) {
- solo_init() ;
- }
- /*
- * Start up the main loop.
- */
- XtAppAddWorkProc( appContext, timeStepWP, (XtPointer)mainview_widget ) ;
- }
- else {
- setTranslations( deadTransTable ) ;
- ol_mode = 1 ;
- }
- GLXwinset( display, radar_ol_window ) ;
- drawOverlay() ;
- }
-
-
-
- static void choose_tank(
- int selection
- )
- {
- switch( selection ) {
-
- case '1' : /* Regular tank */
- top_speed = vmax[0] ;
- new_tank_type = 0 ;
- post_new_message( 0, 1, "Tank is a regular tank." ) ;
- break ;
-
- case '2' : /* Super tank */
- top_speed = vmax[1] ;
- new_tank_type = 1 ;
- post_new_message( 0, 1, "Tank is a super tank." ) ;
- break ;
-
- case '3' : /* Stealth tank */
- top_speed = vmax[2] ;
- new_tank_type = 2 ;
- post_new_message( 0, 1, "Tank is a stealth tank." ) ;
- break ;
-
- case '4' : /* Runner tank */
- top_speed = vmax[3] ;
- new_tank_type = 3 ;
- post_new_message( 0, 1, "Tank is a runner tank." ) ;
- break ;
-
- default: /* Bad argument */
- fprintf( stderr, "Bad argument to tankSelect in resources\n" ) ;
- fprintf( stderr, "Proper argument is either 1, 2, 3, or 4\n" ) ;
- end_program( 0 ) ;
- break ;
-
- }
- picking_tank = FALSE ;
- need_to_set_tank = TRUE ;
- }
-
-
-
- void send_quit_packet( void )
- {
- struct BzAck ack ;
-
- ack.bz_id = BZQUIT ;
- ack.id = player[SELF].id ;
- ack.ack_id = player[SELF].id ;
- ack.key = player[SELF].key ;
-
- /*
- * Send out 3 for good measure.
- */
- send_out( &ack, sizeof( ack ) ) ;
- send_out( &ack, sizeof( ack ) ) ;
- send_out( &ack, sizeof( ack ) ) ;
-
- dprintf( "\n%s: quitting game\n", print_time() ) ;
- if( networking ) {
- validation_summary() ;
- }
-
- sleep( 1 ) ;
-
- }
-
-
-
- static void quit(
- Widget w,
- XEvent *event,
- String *params,
- Cardinal *numParams
- )
- {
- if( !solo )
- send_quit_packet() ;
-
- #if !defined( NETDEBUGGER )
- if( networking && !view_only && !solo ) {
- set_quit_time();
- }
-
- #endif /* !defined( NETDEBUGGER ) */
- end_program( 0 ) ;
- }
-
-
-
- void end_program(
- int status
- )
- {
- end_sound() ;
- exit( status ) ;
- }
-
-
-
- static void stopRandomizing(
- Widget w,
- XEvent *event,
- String *params,
- Cardinal *numParams
- )
- {
- Cardinal zero = 0 ;
- Cardinal one = 1 ;
- static char *two_str = "2" ;
- static char *four_str = "4" ;
-
- randomizer = False ;
- screen_mode = INTRO_PICK_SCREEN ;
- XRaiseWindow( display, radar_window ) ;
- XRaiseWindow( display, mainview_window ) ;
-
- GLXwinset( display, base_window ) ;
- redraw_base_screen() ;
-
- post_new_message( 0, 0, " " ) ;
- mail.out_message[0] = '\0' ;
-
- if( view_only ) {
- tankSelect( w, event, params, &zero ) ;
- }
- else if( solo ) {
- if( kids_mode ) {
- tankSelect( w, event, &four_str, &one ) ;
- }
- else {
- tankSelect( w, event, &two_str, &one ) ;
- }
- }
- else {
- setTranslations( introPickTransTable ) ;
- ol_mode = 1 ;
- }
-
- XtManageChild( radar_widget ) ;
-
- GLXwinset( display, radar_ol_window ) ;
- drawOverlay() ;
-
- GLXwinset( display, mainview_window ) ;
- redraw_main_view() ;
- }
-
-
-
- static Boolean randomizerWP(
- XtPointer ignore
- )
- {
- rand() ;
- return( !randomizer ) ;
- }
-
-
-
- void draw_intro_screen( void )
- {
- viewport( 0, screen_w, 0, screen_h ) ;
- ortho2( -0.5f, (float)screen_w-0.5f, -0.5f, (float)screen_h-0.5f ) ;
- color( black ) ;
- clear() ;
- color( yellow ) ;
- print_help( (float)screen_w / 2.f, (float)screen_h / 2.f, 1 ) ;
- }
-
-
-
- static char *normal_instructions[] = {
- " left mouse - fire regular missile",
- "Nmid mouse - fire guided missile",
- "N (or return control to",
- "N tank from missile)",
- " right mouse - identify player",
- " mouse x,y - control tank",
- "N or guided missile",
- " a - zoom out radar",
- " b - toggle binoculars",
- "Nc - drop enemy flag",
- " d - drop mine",
- "N (can be detonated by x)",
- " D - drop permanent mine",
- "Nf - grab enemy flag",
- " l - toggle logos",
- " h - show help screen",
- "Nm - send mail to all",
- " p - pick up mine",
- "SP - pause/resume game",
- "Ns - show scores",
- " S - toggle sounds",
- "Nt - send mail to team",
- " x - detonate mine",
- " z - zoom in radar",
- " up/down - adjust volume",
- " ESC - quit", } ;
-
- static char *view_only_instructions[] = {
- " right mouse - identify player",
- " mouse x,y - control tank",
- " a - zoom out radar",
- " b - toggle binoculars",
- " c - toggle copilot view",
- " l - toggle logos",
- " h - show help screen",
- " n - next copilot view",
- " s - show scores",
- " S - toggle sounds",
- " z - zoom in radar",
- " up/down - adjust volume",
- " ESC - quit", } ;
-
-
- static void print_help(
- float sx,
- float sy,
- int prompt
- )
- {
- float xx ;
- float yy ;
- float dyi ;
- float dyj ;
- int i ;
- int k ;
- int n ;
- char key ;
- char **line ;
- char vers[40] ;
- char **instructions ;
-
- /*
- * Indentify the instruction set for view-only mode and determine the
- * number of lines.
- */
- if( view_only ) {
- instructions = view_only_instructions ;
- i = sizeof( view_only_instructions ) /
- sizeof( view_only_instructions[0] ) ;
- }
- else {
- instructions = normal_instructions ;
- i = sizeof( normal_instructions ) / sizeof( normal_instructions[0] ) ;
- }
-
- /*
- * Identify a key for which instruction lines should be printed out.
- */
- if( solo ) {
- key = 'S' ;
- }
- else {
- key = 'N' ;
- }
-
- /*
- * Adjust the number of lines (based on solo or networking).
- */
- n = 0 ;
- for( k = 0 ; k < i ; k++ ) {
- if( instructions[k][0] == ' ' || instructions[k][0] == key )
- n++ ;
- }
- i = n ;
-
- dyi = char_height * 1.25f ;
- dyj = char_height * 1.1f ;
-
- /*
- * Calculate line spacing.
- */
- do {
- xx = sx - 15.f*char_width/2.f ;
- yy = ( ( i + 2 ) * dyi + 2 * dyj ) / 2.f + 20.f ;
- if( view_only )
- yy += dyi ;
- if( prompt ) {
- yy += ( dyi + 3 * dyj ) / 2.f ;
- }
- if( yy > sy ) {
- dyi *= .95f ;
- dyj *= .95f ;
- }
- } while( yy > sy ) ;
- yy += sy - 20.f ;
-
- /*
- * Start printing headers.
- */
- cmov2( xx, yy ) ;
- charstr( "BZ INSTRUCTIONS" ) ;
- yy -= dyi ;
- #if defined(BETA)
- sprintf( vers, "Beta Version %s", print_version() ) ;
- #else
- sprintf( vers, "Version %s", print_version() ) ;
- #endif /* defined(BETA) */
- xx = sx - strlen( vers ) * char_width / 2.f ;
- cmov2( xx, yy ) ;
- charstr( vers ) ;
- if( view_only ) {
- yy -= dyi ;
- xx = sx - 14.f * char_width / 2.f ;
- cmov2( xx, yy ) ;
- charstr( "View Only Mode" ) ;
- }
- yy -= 2 * dyi ;
-
- /*
- * Print out the instructions.
- */
- xx = sx - strlen( instructions[0] ) * char_width / 2.f ;
- line = instructions ;
- while( i-- ) {
- yy -= dyi ;
- cmov2( xx, yy ) ;
- /*
- * Skip lines not for current solo/networking mode.
- */
- while( line[0][0] != ' ' && line[0][0] != key )
- line++ ;
- charstr( *(line++) + 1 ) ;
- }
-
- if( prompt ) {
- yy -= 3 * dyj ;
- xx = sx - 38.f*char_width/2.f ;
- cmov2( xx, yy ) ;
- charstr( "Hit any key to continue (ESC to quit):" ) ;
- }
- }
-
-
-
- static void setTranslations(
- XtTranslations transTable
- )
- {
- int n ;
-
- n = 0 ;
- XtSetArg( wargs[n], XmNtranslations, transTable ) ; n++ ;
- XtSetValues( mainview_widget, wargs, n ) ;
- XtSetValues( radar_widget, wargs, n ) ;
- XtSetValues( base_widget, wargs, n ) ;
- }
-
-
- static void identifyTank(
- Widget w,
- XEvent *event,
- String *params,
- Cardinal *numParams
- )
- {
- want_to_identify = TRUE ;
- }
-
-
-
- static void fireNormalShot(
- Widget w,
- XEvent *event,
- String *params,
- Cardinal *numParams
- )
- {
- if( loading_missile == 0 ) {
- fire_normal_missile = TRUE ;
- }
- }
-
-
-
- static void fireGuidedShot(
- Widget w,
- XEvent *event,
- String *params,
- Cardinal *numParams
- )
- {
- if( solo && !kids_mode ) {
- post_new_message( 0, 1, "Can't fire guided missiles in solo mode." ) ;
- }
- else if( loading_missile == 0 ) {
- if( kids_mode || player[SELF].tank_type != 3 ) {
- fire_guided_missile = TRUE ;
- }
- else {
- post_new_message( 0, 1,
- "This tank type can not fire guided missiles." ) ;
- }
- }
- else if( guiding ) {
- quit_guided_missile = TRUE ;
- }
- }
-
-
-
- static void toggleShowTimings(
- Widget w,
- XEvent *event,
- String *params,
- Cardinal *numParams
- )
- {
- want_to_see_timings = !want_to_see_timings ;
- post_new_message( 0, 0, "Timing display %s.\n",
- ( want_to_see_timings ) ? "on" : "off" ) ;
- }
-
-
-
- static void toggleShowScore(
- Widget w,
- XEvent *event,
- String *params,
- Cardinal *numParams
- )
- {
- if( !solo )
- want_to_see_score = !want_to_see_score ;
- }
-
-
-
- static void toggleShowHelp(
- Widget w,
- XEvent *event,
- String *params,
- Cardinal *numParams
- )
- {
- want_to_see_help = !want_to_see_help ;
- }
-
-
-
- static void zoomIn(
- Widget w,
- XEvent *event,
- String *params,
- Cardinal *numParams
- )
- {
- if( zoom_level < sizeof( zoom_settings ) / sizeof( zoom_settings[0] ) - 1 ){
- zoom_factor = zoom_settings[++zoom_level] ;
- need_to_show_zoom = TRUE ;
- }
- }
-
-
-
- static void nextCoPilot(
- Widget w,
- XEvent *event,
- String *params,
- Cardinal *numParams
- )
- {
- if( show_copilot_view ) {
- next_copilot_view() ;
- }
- }
-
-
-
- static void coPilot(
- Widget w,
- XEvent *event,
- String *params,
- Cardinal *numParams
- )
- {
- if( show_copilot_view ) {
- show_copilot_view = FALSE ;
- post_new_message( 0, 0, "Co-pilot mode off." ) ;
- }
- else if( number_players > 1 ) {
- show_copilot_view = TRUE ;
- if( copilot_player > number_players ) {
- copilot_player = 1 ;
- }
- post_new_message( 0, 0, "Co-pilot view of %s.",
- player[copilot_player].name ) ;
- }
- }
-
-
-
- static void zoomOut(
- Widget w,
- XEvent *event,
- String *params,
- Cardinal *numParams
- )
- {
- if( zoom_level > 0 ) {
- zoom_factor = zoom_settings[--zoom_level] ;
- need_to_show_zoom = TRUE ;
- }
- }
-
-
-
- static void dropMine(
- Widget w,
- XEvent *event,
- String *params,
- Cardinal *numParams
- )
- {
- want_to_drop_normal_mine = TRUE ;
- }
-
-
-
- static void grabFlag(
- Widget w,
- XEvent *event,
- String *params,
- Cardinal *numParams
- )
- {
- if( show_flags && !HAS_A_FLAG( player[SELF] ) )
- want_to_grab_flag = TRUE ;
- }
-
-
-
- static void dropFlag(
- Widget w,
- XEvent *event,
- String *params,
- Cardinal *numParams
- )
- {
- if( show_flags && HAS_A_FLAG( player[SELF] ) )
- want_to_drop_flag = TRUE ;
- }
-
-
-
- static void detonateMine(
- Widget w,
- XEvent *event,
- String *params,
- Cardinal *numParams
- )
- {
- if( mine_status > 0 ) {
- want_to_detonate_mine = TRUE ;
- }
- }
-
-
-
- static void dropPermanentMine(
- Widget w,
- XEvent *event,
- String *params,
- Cardinal *numParams
- )
- {
- want_to_drop_permanent_mine = TRUE ;
- }
-
-
-
- static void pickUpMine(
- Widget w,
- XEvent *event,
- String *params,
- Cardinal *numParams
- )
- {
- if( mine_status > 0 )
- want_to_pick_mine = TRUE ;
- }
-
-
-
- static void selfDestruct(
- Widget w,
- XEvent *event,
- String *params,
- Cardinal *numParams
- )
- {
- blow_up_self( SELF ) ;
- }
-
-
-
- static void slowDown(
- Widget w,
- XEvent *event,
- String *params,
- Cardinal *numParams
- )
- {
- want_to_slow_down = TRUE ;
- }
-
-
-
- static void resetGun(
- Widget w,
- XEvent *event,
- String *params,
- Cardinal *numParams
- )
- {
- if( loading_missile > 0 ) {
- loading_missile = 0 ;
- if( guiding ) {
- left_track = right_track = 0.f ;
- guiding = FALSE ;
- reset_mouse() ;
- }
- }
- }
-
-
-
- static void stopWatch(
- Widget w,
- XEvent *event,
- String *params,
- Cardinal *numParams
- )
- {
- static int mode = 0 ;
- static struct timeval watch_time ;
- float et ;
-
- if( mode == 0 ) {
- start_time( &watch_time ) ;
- mode = 1 ;
- }
- else {
- mode = 0 ;
- et = end_time( &watch_time, NULL ) ;
- post_new_message( 0, 0, "Time: %.3f secs.", et ) ;
- }
- }
-
-
-
- static void mouseTrack(
- Widget w,
- XEvent *event,
- String *params,
- Cardinal *numParams
- )
- {
- XMotionEvent *xmotion = &(event->xmotion) ;
-
- if( event->type == MotionNotify ) {
- mouse_interpret( xmotion->x_root, xmotion->y_root ) ;
- }
- }
-
-
-
- static void reset_mouse( void )
- {
- int xc ;
- int yc ;
-
- xc = ( VPMVIEW_R + VPMVIEW_L ) / 2 ;
- yc = screen_h - ( VPMVIEW_T + VPMVIEW_B ) / 2 ;
-
- XWarpPointer( display, None, XtWindow( toplevel ), 0, 0, 0, 0, xc, yc ) ;
- XFlush( display ) ;
- }
-
-
-
- static void reinterpret_mouse( void )
- {
- Window root_win ;
- Window child_win ;
- int root_x ;
- int root_y ;
- int win_x ;
- int win_y ;
- unsigned int mask ;
-
- if( XQueryPointer( display, XtWindow( toplevel ), &root_win, &child_win,
- &root_x, &root_y, &win_x, &win_y, &mask ) ) {
- mouse_interpret( win_x, win_y ) ;
- }
- }
-
-
-
- static void mouse_interpret(
- int mouse_x,
- int mouse_y
- )
- {
- static int xc ;
- static int yc ;
- static int init = 1 ;
- float x ;
- float y ;
- float s ;
- float track_radius ;
-
- if( init ) {
- init = 0 ;
- xc = ( VPMVIEW_R + VPMVIEW_L ) / 2 ;
- yc = ( VPMVIEW_T + VPMVIEW_B ) / 2 ;
- }
-
- if( view_only ) {
- track_radius = VIEW_ONLY_TRACK_RADIUS ;
- }
- else {
- track_radius = NORMAL_TRACK_RADIUS ;
- }
-
- /*
- * Guiding a missile...
- */
- if( guiding ) {
- x = (float)( mouse_x - xc ) ;
- y = 0.f ;
- s = ( x > 0.0f ) ? x : -x ;
- if( s > 0.0f ) {
- if( s < 5.f ) {
- x = 0.0f ;
- }
- else {
- if( s < track_radius )
- s = track_radius ;
- x /= s ;
- }
- }
-
- if( x > 0.0f ) {
- left_track_engaged = x ;
- right_track_engaged = 0.0f ;
- }
- else {
- left_track_engaged = 0.0f ;
- right_track_engaged = -x ;
- }
- }
- /*
- * Steering the tank..
- */
- else {
- x = (float)( mouse_x - xc ) ;
- y = (float)( yc - ( screen_h - mouse_y ) ) ;
-
- if( ( s = hypotn( x, y ) ) > 0.0f ) {
- if( s < 10.f ) {
- x = y = 0.0f ;
- }
- else {
- if( s < track_radius )
- s = track_radius ;
- x /= s ;
- y /= s ;
- x *= ( x > 0.f ) ? x : -x ;
- y *= ( y > 0.f ) ? y : -y ;
- }
- }
-
- left_track_engaged = x - y ;
- right_track_engaged = -x - y ;
- }
- }
-
-
-
- static void changeTank(
- Widget w,
- XEvent *event,
- String *params,
- Cardinal *numParams
- )
- {
- picking_tank = TRUE ;
- setTranslations( introPickTransTable ) ;
- GLXwinset( display, radar_ol_window ) ;
- drawOverlay() ;
- ringbell() ;
- }
-
-
-
- static void writeMail(
- Widget w,
- XEvent *event,
- String *params,
- Cardinal *numParams
- )
- {
- if( !solo ) {
- GLXwinset( display, base_window ) ;
- input_message( 1 ) ;
- sending_msg = SENDING_ALL_MAIL ;
- if( IS_ALIVE( player[SELF] ) ) {
- setTranslations( liveMailTransTable ) ;
- }
- else {
- setTranslations( deadMailTransTable ) ;
- ol_mode = 0 ;
- GLXwinset( display, radar_ol_window ) ;
- drawOverlay() ;
- }
- ringbell() ;
- }
- }
-
-
-
- static void writeTeamMail(
- Widget w,
- XEvent *event,
- String *params,
- Cardinal *numParams
- )
- {
- if( !solo ) {
- GLXwinset( display, base_window ) ;
- input_message( 1 ) ;
- sending_msg = SENDING_TEAM_MAIL ;
- if( IS_ALIVE( player[SELF] ) ) {
- setTranslations( liveMailTransTable ) ;
- }
- else {
- setTranslations( deadMailTransTable ) ;
- ol_mode = 0 ;
- GLXwinset( display, radar_ol_window ) ;
- drawOverlay() ;
- }
- ringbell() ;
- }
- }
-
-
-
- static void composeMail(
- Widget w,
- XEvent *event,
- String *params,
- Cardinal *numParams
- )
- {
- XKeyEvent *xkey = &(event->xkey) ;
-
- if( event->type == KeyPress && mail_ptr < MAIL_MSG_SIZE ) {
- mail_ptr += XLookupString( xkey, mail_buffer+mail_ptr,
- MAIL_MSG_SIZE - 1 - mail_ptr, NULL, NULL ) ;
- }
- }
-
-
-
- static void toggleBinoculars(
- Widget w,
- XEvent *event,
- String *params,
- Cardinal *numParams
- )
- {
- binoculars = !binoculars ;
- post_new_message( 0, 0, "Binoculars %s.\n", binoculars ? "on" : "off" ) ;
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Join the blue team.
- *----------------------------------------------------------------------------*/
- static void joinBlueTeam(
- Widget w,
- XEvent *event,
- String *params,
- Cardinal *numParams
- )
- {
- if( player[SELF].team == NEUTRAL_TEAM ) {
- join_a_team( BLUE_TEAM ) ;
- }
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Join the red team.
- *----------------------------------------------------------------------------*/
- static void joinRedTeam(
- Widget w,
- XEvent *event,
- String *params,
- Cardinal *numParams
- )
- {
- if( player[SELF].team == NEUTRAL_TEAM ) {
- join_a_team( RED_TEAM ) ;
- }
- }
-
-
-
- static void toggleLogos(
- Widget w,
- XEvent *event,
- String *params,
- Cardinal *numParams
- )
- {
- show_logos = !show_logos ;
- post_new_message( 0, 0, "Logos %s.\n", show_logos ? "on" : "off" ) ;
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Toggle pause function on and off.
- *----------------------------------------------------------------------------*/
- static void togglePause(
- Widget w,
- XEvent *event,
- String *params,
- Cardinal *numParams
- )
- {
- if( solo ) {
- paused = !paused ;
- if( paused ) {
- post_new_message( 0, 0, " " ) ;
- post_new_message( 0, 0, "Paused...(hit P to continue)." ) ;
- start_pause() ;
- }
- else {
- post_new_message( 0, 1, "Play resumed." ) ;
- end_pause() ;
- }
- }
- }
-
-
-
- static void toggleAudio(
- Widget w,
- XEvent *event,
- String *params,
- Cardinal *numParams
- )
- {
- no_sfx = !toggle_sound() ;
- post_new_message( 0, 0, "Sound is %s.\n", no_sfx ? "off" : "on" ) ;
- }
-
-
-
- static void installColormapWithOverlay( void )
- {
- Window windows[7];
- Window over_lay ;
- Window popup ;
- Window under_lay ;
- Arg args[5] ;
- int i ;
-
- i = 0 ;
- XtSetArg( args[i], GlxNoverlayWindow, &over_lay ) ; i++ ;
- XtSetArg( args[i], GlxNpopupWindow, &popup ) ; i++ ;
- XtSetArg( args[i], GlxNunderlayWindow, &under_lay ) ; i++ ;
- XtGetValues( radar_widget, args, i ) ;
-
- i = 0 ;
- if( over_lay ) {
- windows[i] = over_lay ;
- i++ ;
- }
- if( popup ) {
- windows[i] = popup ;
- i++ ;
- }
- if( under_lay ) {
- windows[i] = under_lay ;
- i++ ;
- }
-
- windows[i] = XtWindow( radar_widget ) ; i++ ;
- windows[i] = XtWindow( mainview_widget ) ; i++ ;
- windows[i] = XtWindow( base_widget ) ; i++ ;
- windows[i] = XtWindow( toplevel ) ; i++ ;
- XSetWMColormapWindows( XtDisplay( toplevel ), XtWindow( toplevel ),
- windows, i ) ;
- }
-
-
-
- void change_cursor( void )
- {
- Colormap cmap ;
- static Cursor bz_cursor = (Cursor)NULL ;
- XColor fg ;
- XColor bg ;
-
- /* define an appropriate busy cursor */
- if( bz_cursor == (Cursor)NULL ) {
- fg.pixel = AppRes.cursorForeground ;
- bg.pixel = AppRes.cursorBackground ;
- cmap = DefaultColormap( display, DefaultScreen(display) ) ;
- XQueryColor( display, cmap, &fg ) ;
- XQueryColor( display, cmap, &bg ) ;
- bz_cursor = AppRes.cursor ;
- XRecolorCursor( display, bz_cursor, &fg, &bg ) ;
- }
- XDefineCursor( display, XtWindow( radar_widget ), bz_cursor ) ;
- XDefineCursor( display, XtWindow( mainview_widget ), bz_cursor ) ;
- XDefineCursor( display, XtWindow( base_widget ), bz_cursor ) ;
- XDefineCursor( display, XtWindow( toplevel ), bz_cursor ) ;
- XFlush( display ) ;
- }
-
-
-
- static void setName( void )
- {
- char *name ;
-
- if( strlen( player_name ) == 0 ) {
- if( ( name = getenv( "BZ_ID" ) ) != NULL ) {
- strncpy( player_name, name, NAMELEN ) ;
- }
- else if( AppRes.identifier != NULL && strlen(AppRes.identifier) > 0 ) {
- strncpy( player_name, AppRes.identifier, NAMELEN ) ;
- }
- else {
- cuserid( player_name ) ;
- }
- }
- strncpy( player[SELF].name, player_name, NAMELEN ) ;
- player[SELF].name[NAMELEN-1] = '\0' ;
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Next Co-pilot View - get next player for copilot view.
- *----------------------------------------------------------------------------*/
- static void next_copilot_view( void )
- {
- if( number_players > 1 ) {
- copilot_player++ ;
- if( copilot_player >= number_players )
- copilot_player = 1 ;
- post_new_message( 0, 0, "Co-pilot view of %s.",
- player[copilot_player].name ) ;
- }
- else {
- show_copilot_view = FALSE ;
- }
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Join a team (either red or blue).
- *----------------------------------------------------------------------------*/
- static void join_a_team(
- int team
- )
- {
- player[SELF].team = team ;
- GLXwinset( display, radar_ol_window ) ;
- drawOverlay() ;
- set_bulletin_color( teamColor[player[SELF].team] ) ;
- post_new_message( 0, 1, "Assigned to %s team.", teamName[team] ) ;
- GLXwinset( display, base_window ) ;
- redraw_base_screen() ;
- if( !show_flags && !never_have_flag ) {
- if( player[SELF].team == RED_TEAM ) {
- red_team_present = TRUE ;
- }
- else if( player[SELF].team == BLUE_TEAM ) {
- blue_team_present = TRUE ;
- }
- if( red_team_present && blue_team_present ) {
- show_flags = TRUE ;
- post_new_message( 0, 1, "Flag capturing enabled." ) ;
- }
- }
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Send a preset message to all.
- *----------------------------------------------------------------------------*/
- static void sendPresetTeamMail(
- Widget w,
- XEvent *event,
- String *params,
- Cardinal *numParams
- )
- {
- int selection ;
- char *s ;
-
- if( solo ) {
- return ;
- }
-
- if( *numParams == 0 ) {
- selection = 1 ;
- }
- else {
- selection = atoi( params[0] ) ;
- }
-
- switch( selection ) {
-
- case 1 :
- s = AppRes.message1 ;
- break ;
-
- case 2 :
- s = AppRes.message2 ;
- break ;
-
- case 3 :
- s = AppRes.message3 ;
- break ;
-
- case 4 :
- s = AppRes.message4 ;
- break ;
-
- case 5 :
- s = AppRes.message5 ;
- break ;
-
- default :
- return ;
- }
-
- if( s && s[0] ) {
- writeTeamMail( w, event, params, numParams ) ;
- strncpy( mail_buffer, s, sizeof( mail_buffer ) - 1 ) ;
- mail_ptr = strlen( mail_buffer ) ;
- if( mail_buffer[mail_ptr-1] == '&' ) {
- mail_buffer[mail_ptr-1] = '\r' ;
- }
- }
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Send a preset message to all.
- *----------------------------------------------------------------------------*/
- static void sendPresetMail(
- Widget w,
- XEvent *event,
- String *params,
- Cardinal *numParams
- )
- {
- int selection ;
- char *s ;
-
- if( solo ) {
- return ;
- }
-
- if( *numParams == 0 ) {
- selection = 1 ;
- }
- else {
- selection = atoi( params[0] ) ;
- }
-
- switch( selection ) {
-
- case 1 :
- s = AppRes.message1 ;
- break ;
-
- case 2 :
- s = AppRes.message2 ;
- break ;
-
- case 3 :
- s = AppRes.message3 ;
- break ;
-
- case 4 :
- s = AppRes.message4 ;
- break ;
-
- case 5 :
- s = AppRes.message5 ;
- break ;
-
- default :
- return ;
- }
-
- if( s && s[0] ) {
- writeMail( w, event, params, numParams ) ;
- strncpy( mail_buffer, s, sizeof( mail_buffer ) - 1 ) ;
- mail_ptr = strlen( mail_buffer ) ;
- if( mail_buffer[mail_ptr-1] == '&' ) {
- mail_buffer[mail_ptr-1] = '\r' ;
- }
- }
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Reset the viewing order (intialize).
- *----------------------------------------------------------------------------*/
- void reset_viewing_order( void )
- {
- int i ;
-
- for( i = 0 ; i < TOTALOBJS ; i++ ) {
- view_order[i] = i ;
- dst[i] = 0.0f ;
- }
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Put the version number in a string.
- *----------------------------------------------------------------------------*/
- char *print_version( void )
- {
- long id = ( BZ & 0x00ff ) + 15 ;
- static char s[10] ;
-
- sprintf( s, "%d.%d.4", id / 10, id % 10 ) ;
-
- return( s ) ;
- }
-