home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / demos / audio / bz / bzbase.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  26.1 KB  |  1,215 lines

  1. /*
  2.  * Copyright (C) 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /***************************************************************************
  18.  *
  19.  * BZ - Multiplayer tank game.
  20.  *
  21.  * $Id: bzbase.c,v 1.5 1993/08/11 19:45:43 adele Exp $
  22.  *
  23.  *                    Chris Fouts - Silicon Graphics, Inc.
  24.  *                    October, 1991
  25.  **************************************************************************/
  26. #include <stdio.h>
  27. #include <stdarg.h>
  28. #include <math.h>
  29. #include <malloc.h>
  30. #include <X11/Intrinsic.h>
  31. #include <Xm/Xm.h>
  32. #include <X11/Xirisw/GlxMDraw.h>
  33. #include <gl/gl.h>
  34. #include "bz.h"
  35. #include "bzscreen.h"
  36. #include "bzobjs.h"
  37. #include "bzbase.h"
  38.  
  39. /* BEGIN PROTOTYPES -S bzbase.c */
  40. static void frame( float x01, float y01, float x02, float y02, Colorindex c0,
  41.                 Colorindex c1, float w ) ;
  42. static void init_bulletin( void ) ;
  43. static void show_number( int value, int places, float x, float y,
  44.                 Colorindex bg, Colorindex fg ) ;
  45. static void show_pick_tank_instructions( void ) ;
  46. static void show_something( float l, float b, float r, float t, int value,
  47.                 int places, Colorindex bg, Colorindex fg ) ;
  48. static void show_speed_util( float track, float l, float b, float r,
  49.                 float t ) ;
  50. static void title( int left, int bottom, int right, char *s ) ;
  51. /* END PROTOTYPES -S bzbase.c */
  52.  
  53. static char    *version_id = "$Id: bzbase.c,v 1.5 1993/08/11 19:45:43 adele Exp $" ;
  54.  
  55.  
  56. /*
  57.  * Screen position variables.
  58.  */
  59. DECLARE( MVIEW ) ;
  60. DECLARE( RADAR ) ;
  61. DECLARE( HEAD ) ;
  62. DECLARE( LOADM ) ;
  63. DECLARE( READY ) ;
  64. DECLARE( SCORE ) ;
  65. DECLARE( LIVES ) ;
  66. DECLARE( LEVEL ) ;
  67. DECLARE( NOPLY ) ;
  68. DECLARE( RIGHT ) ;
  69. DECLARE( LEFTT ) ;
  70. DECLARE( LOGOD ) ;
  71. DECLARE( MESGS ) ;
  72. DECLARE( OUTMS ) ;
  73. DECLARE( GROND ) ;
  74. DECLARE( MINES ) ;
  75. DECLARE( FLAGS ) ;
  76. extern float        char_width ;
  77. extern float        char_height ;
  78. extern float        mv_w ;
  79. extern float        mv_h ;
  80. extern float        mv_m ;
  81. extern long            screen_w, screen_h ;
  82.  
  83. extern Boolean        db_base ;
  84. extern Matrix        id_mat ;
  85. Colorindex            ramp0 ;
  86. Colorindex            ramp1 ;
  87. Colorindex            ramp2 ;
  88. Colorindex            ramp3 ;
  89. Colorindex            ramp4 ;
  90. extern Colorindex    black ;
  91. extern Colorindex    white ;
  92. extern Colorindex    red ;
  93. extern Colorindex    blue ;
  94. extern Colorindex    green ;
  95. extern Colorindex    yellow ;
  96.  
  97. char                msgs[POST_MSG_SIZE] ;
  98. int                    msg_count ;
  99. int                    msg_redraw = 0 ;
  100. int                    max_msg_lines ;
  101. typedef char        BulletinLine[POST_MSG_SIZE+1] ;
  102. static BulletinLine    *bulletin ;
  103. static Colorindex    *bulletin_color ;
  104. static int            bulletin_line = 1 ;
  105. static Colorindex    current_bulletin_color ;
  106. extern unsigned int    sending_msg ;
  107.  
  108. GL_Object                radar1 ;
  109. extern GL_Object        digit[10][2] ;
  110. extern struct BzMember    player[] ;
  111. extern struct BzNotice    mail ;
  112.  
  113. extern Window    base_window ;
  114. extern Window    radar_window ;
  115. extern Window    radar_ol_window ;
  116.  
  117. extern char            *basename ;
  118. extern Boolean        blue_flag_held ;
  119. extern GL_Object    border ;
  120. extern float        digit_sx ;
  121. extern float        digit_sy ;
  122. extern Display        *display ;
  123. extern GL_Object    flag_homes ;
  124. extern float        flag_x[] ;
  125. extern float        flag_y[] ;
  126. extern Colorindex    ground_color ;
  127. extern Boolean        guiding ;
  128. extern int            init_wait ;
  129. extern float        left_track ;
  130. extern unsigned int    level ;
  131. extern unsigned int    lives ;
  132. extern long            loading_missile ;
  133. extern unsigned int    mine_left ;
  134. extern int            need_to_show_msgs_vocal ;
  135. extern Boolean        need_to_show_msgs ;
  136. extern Boolean        never_have_flag ;
  137. extern GL_Object    null_obj ;
  138. extern unsigned int    number_players ;
  139. extern float        obst_x[] ;
  140. extern float        obst_y[] ;
  141. extern int            ol_mode ;
  142. extern int            perm_mine ;
  143. extern Boolean        picking_tank ;
  144. extern Boolean        red_flag_held ;
  145. extern float        right_track ;
  146. extern int            screen_mode ;
  147. extern long            screen_w, screen_h ;
  148. extern Boolean        show_flags ;
  149. extern Boolean        solo ;
  150. extern GL_Object    tank_logo[] ;
  151. extern Colorindex    teamColor[] ;
  152. extern Widget        toplevel ;
  153. extern float        top_speed ;
  154. extern Boolean        use_pups ;
  155. extern Boolean        view_only ;
  156. extern float        obst_y[] ;
  157. extern unsigned int    number_players ;
  158. extern Colorindex    teamColor[] ;
  159. extern int            mine_status ;
  160. extern int            perm_mine ;
  161. extern float        mine_x ;
  162. extern float        mine_y ;
  163. extern Boolean        binoculars ;
  164. extern Arg            wargs[] ;
  165. extern float        zoom_factor ;
  166.  
  167.  
  168.  
  169. void redraw_base_screen( void )
  170. {
  171.     switch( screen_mode ) {
  172.  
  173.         case MAIN_SCREEN :
  174.         case INTRO_PICK_SCREEN :
  175.             init_screen() ;
  176.             show_msgs( 0, 1 ) ;
  177.             show_heading() ;
  178.             show_speed() ;
  179.             show_mine_status() ;
  180.             show_flag_status() ;
  181.             show_out_message() ;
  182.             show_gun_status( loading_missile - 1 ) ;
  183.             break ;
  184.  
  185.         case INTRO_SCREEN :
  186.             draw_intro_screen() ;
  187.             break ;
  188.  
  189.         }
  190.     gflush() ;
  191.     if( db_base ) swapbuffers();
  192. }
  193.  
  194.  
  195.  
  196. void init_screen( void )
  197. {
  198. #if !defined( NETDEBUGGER )
  199.     reshapeviewport() ;
  200.     if( db_base ) frontbuffer(1);
  201.     loadmatrix( id_mat ) ;
  202.     ortho2( -0.5f, (float)screen_w-0.5f, -0.5f, (float)screen_h-0.5f ) ;
  203.  
  204.     color(ramp3);
  205.     clear() ;
  206.  
  207.     bgnpolygon() ;
  208.         color( ramp3 ) ;
  209.         vertex2f( 0.f, 0.f) ;
  210.         color( ramp2 ) ;
  211.         vertex2f( 0.f, FVPMVIEW_B-FRAMEW ) ;
  212.         color( ramp3 ) ;
  213.         vertex2f( (float)screen_w, FVPMVIEW_B-FRAMEW ) ;
  214.     endpolygon();
  215.     bgnpolygon() ;
  216.         color( ramp3);
  217.         vertex2f( 0.f, 0.f ) ;
  218.         color( ramp2);
  219.         vertex2f( (float)screen_w, 0.f ) ;
  220.         color( ramp3);
  221.         vertex2f( (float)screen_w, FVPMVIEW_B-FRAMEW ) ;
  222.     endpolygon();
  223.  
  224.     pushviewport() ;
  225.     viewport( VPLOGOD_L, VPLOGOD_R, VPLOGOD_B, VPLOGOD_T ) ;
  226.     ortho2( -5.f, 270.f, -15.f, 260.f ) ;
  227.     color( ramp4 ) ;
  228.     if( tank_logo[SELF] != null_obj ) {
  229.         callobj( tank_logo[SELF] ) ;
  230.         }
  231.     else {
  232.         rectf( 50.f, 50.f, 205.f, 205.f ) ;
  233.         }
  234.     ortho2( -15.f, 260.f, -5.f, 270.f ) ;
  235.     color( black ) ;
  236.     if( tank_logo[SELF] != null_obj ) {
  237.         callobj( tank_logo[SELF] ) ;
  238.         }
  239.     else {
  240.         rectf( 50.f, 50.f, 205.f, 205.f ) ;
  241.         }
  242.     ortho2( -10.f, 265.f, -10.f, 265.f ) ;
  243.     if( player[SELF].team == RED_TEAM )    {
  244.         color( red ) ;
  245.         }
  246.     else if( player[SELF].team == BLUE_TEAM ) {
  247.         color( blue ) ;
  248.         }
  249.     else {
  250.         color( green ) ;
  251.         }
  252.     if( tank_logo[SELF] != null_obj ) {
  253.         callobj( tank_logo[SELF] ) ;
  254.         }
  255.     else {
  256.         rectf( 50.f, 50.f, 205.f, 205.f ) ;
  257.         }
  258.     popviewport() ;
  259.     ortho2( -0.5f, (float)screen_w-0.5f, -0.5f, (float)screen_h-0.5f ) ;
  260.  
  261.     frame( FVPMVIEW_L, FVPMVIEW_B, FVPMVIEW_R, FVPMVIEW_T,
  262.         ramp0, ramp1, FRAMEW ) ;
  263.     frame( FVPRADAR_L, FVPRADAR_B, FVPRADAR_R, FVPRADAR_T,
  264.         ramp0, ramp1, FRAMEW ) ;
  265.     frame( FVPHEAD_L, FVPHEAD_B, FVPHEAD_R, FVPHEAD_T,
  266.         ramp0, ramp1, FRAMEW ) ;
  267.     title( VPHEAD_L, VPHEAD_B, VPHEAD_R, "HEADING" ) ;
  268.  
  269.     frame( FVPLOADM_L, FVPLOADM_B, FVPLOADM_R, FVPLOADM_T,
  270.         ramp0, ramp1, FRAMEW ) ;
  271.     title( VPLOADM_L, VPLOADM_B, VPLOADM_R, "STATUS" ) ;
  272.  
  273.     frame( FVPREADY_L, FVPREADY_B, FVPREADY_R, FVPREADY_T,
  274.         ramp0, ramp1 ,FRAMEW ) ;
  275.     title( VPREADY_L, VPREADY_B, VPREADY_R, "STATUS" ) ;
  276.  
  277.     frame( FVPSCORE_L, FVPSCORE_B, FVPSCORE_R, FVPSCORE_T,
  278.         ramp0, ramp1, FRAMEW ) ;
  279.     title( VPSCORE_L, VPSCORE_B, VPSCORE_R, "SCORE" ) ;
  280.  
  281.     frame( FVPLIVES_L, FVPLIVES_B, FVPLIVES_R, FVPLIVES_T,
  282.         ramp0, ramp1, FRAMEW ) ;
  283.     title( VPLIVES_L, VPLIVES_B, VPLIVES_R, "LIVES" ) ;
  284.  
  285.     frame( FVPLEVEL_L, FVPLEVEL_B, FVPLEVEL_R, FVPLEVEL_T,
  286.         ramp0, ramp1, FRAMEW ) ;
  287.     title( VPLEVEL_L, VPLEVEL_B, VPLEVEL_R, solo ? "LEVEL" : "KILLS" ) ;
  288.  
  289.     frame( FVPNOPLY_L, FVPNOPLY_B, FVPNOPLY_R, FVPNOPLY_T,
  290.         ramp0, ramp1, FRAMEW ) ;
  291.     title( VPNOPLY_L, VPNOPLY_B, VPNOPLY_R, "PLAYERS" ) ;
  292.  
  293.     frame( FVPRIGHT_L, FVPRIGHT_B, FVPRIGHT_R, FVPRIGHT_T,
  294.         ramp0, ramp1, FRAMEW ) ;
  295.     title( VPRIGHT_L, VPRIGHT_B, VPRIGHT_R, "RIGHT" ) ;
  296.  
  297.     frame( FVPLEFTT_L, FVPLEFTT_B, FVPLEFTT_R, FVPLEFTT_T,
  298.         ramp0, ramp1, FRAMEW ) ;
  299.     title( VPLEFTT_L, VPLEFTT_B, VPLEFTT_R, "LEFT" ) ;
  300.  
  301.     frame( FVPMESGS_L, FVPMESGS_B, FVPMESGS_R, FVPMESGS_T,
  302.         ramp0, ramp1, FRAMEW ) ;
  303.     title( VPMESGS_L, VPMESGS_B, VPMESGS_R, "MESSAGES" ) ;
  304.  
  305.     if( !view_only ) {
  306.         frame( FVPMINES_L, FVPMINES_B, FVPMINES_R, FVPMINES_T,
  307.             ramp0, ramp1, FRAMEW ) ;
  308.         title( VPMINES_L, VPMINES_B, VPMINES_R, "MINE" ) ;
  309.         }
  310.  
  311.     if( !solo && !view_only ) {
  312.         frame( FVPOUTMS_L, FVPOUTMS_B, FVPOUTMS_R, FVPOUTMS_T,
  313.             ramp0, ramp1, FRAMEW ) ;
  314.         title( VPOUTMS_L, VPOUTMS_B, VPOUTMS_R, "MAIL" ) ;
  315.  
  316.         if( !never_have_flag ) {
  317.             frame( FVPFLAGS_L, FVPFLAGS_B, FVPFLAGS_R, FVPFLAGS_T,
  318.                 ramp0, ramp1, FRAMEW ) ;
  319.             title( VPFLAGS_L, VPFLAGS_B, VPFLAGS_R, "FLAG" ) ;
  320.             }
  321.         }
  322.  
  323.     if( db_base ) frontbuffer(0);
  324.     show_score();
  325.     show_lives();
  326.     show_level();
  327.     show_players();
  328. #endif /* !defined( NETDEBUGGER ) */
  329. }
  330.  
  331.  
  332. static void frame(
  333.     float x01,
  334.     float y01,
  335.     float x02,
  336.     float y02,
  337.     Colorindex c0,
  338.     Colorindex c1,
  339.     float w
  340.     )
  341. {
  342.     bgnpolygon() ;
  343.         color(c0);
  344.         vertex2f(x01-w,y01-w);
  345.         color(c0);
  346.         vertex2f(x01-w,y02+w);
  347.         color(c1);
  348.         vertex2f(x01  ,y02  );
  349.         color(c1);
  350.         vertex2f(x01  ,y01  );
  351.     endpolygon() ;
  352.     bgnpolygon() ;
  353.         color(c0);
  354.         vertex2f(x01-w,y02+w);
  355.         color(c0);
  356.         vertex2f(x02+w,y02+w);
  357.         color(c1);
  358.         vertex2f(x02  ,y02  );
  359.         color(c1);
  360.         vertex2f(x01  ,y02  );
  361.     endpolygon() ;
  362.     bgnpolygon() ;
  363.         color(c1);
  364.         vertex2f(x02  ,y01  );
  365.         color(c1);
  366.         vertex2f(x02  ,y02  );
  367.         color(c0);
  368.         vertex2f(x02+w,y02+w);
  369.         color(c0);
  370.         vertex2f(x02+w,y01-w);
  371.     endpolygon() ;
  372.     bgnpolygon() ;
  373.         color(c1);
  374.         vertex2f(x01  ,y01  );
  375.         color(c1);
  376.         vertex2f(x02  ,y01  );
  377.         color(c0);
  378.         vertex2f(x02+w,y01-w);
  379.         color(c0);
  380.         vertex2f(x01-w,y01-w);
  381.     endpolygon() ;
  382. }
  383.  
  384.  
  385.  
  386. void show_mine_status( void )
  387. {
  388.     if( !view_only ) {
  389.         if( db_base ) frontbuffer(1);
  390.         if( mine_left ) {
  391.             color( green ) ;
  392.             }
  393.         else if( perm_mine ) {
  394.             color( red ) ;
  395.             }
  396.         else {
  397.             color( yellow ) ;
  398.             }
  399.         sboxf( FVPMINES_L, FVPMINES_B, FVPMINES_R, FVPMINES_T ) ;
  400.         if( db_base ) frontbuffer(0);
  401.         }
  402. }
  403.  
  404.  
  405.  
  406. void show_flag_status( void )
  407. {
  408.     if( !solo && !view_only ) {
  409.         if( db_base ) frontbuffer(1);
  410.         if( HAS_RED_FLAG( player[SELF] ) ) {
  411.             color( red ) ;
  412.             }
  413.         else if( HAS_BLUE_FLAG( player[SELF] ) ) {
  414.             color( blue ) ;
  415.             }
  416.         else {
  417.             color( black ) ;
  418.             }
  419.         sboxf( FVPFLAGS_L, FVPFLAGS_B, FVPFLAGS_R, FVPFLAGS_T ) ;
  420.         if( db_base ) frontbuffer(0);
  421.         }
  422. }
  423.  
  424.  
  425.  
  426. void show_heading( void )
  427. {
  428. #if !defined( NETDEBUGGER )
  429.     int                i ;
  430.     int                value ;
  431.  
  432.     value = player[SELF].head * 10.f ;
  433.  
  434.     color( black );
  435.     sboxf( FVPHEAD_L, FVPHEAD_B, FVPHEAD_R, FVPHEAD_T ) ;
  436.     color( yellow );
  437.     pushmatrix() ;
  438.     translate( FVPHEAD_L, FVPHEAD_B, 0.f ) ;
  439.     scale( digit_sx, digit_sy, 0.f ) ;
  440.     translate( 4 * 12.f + 5.f, 5.f, 0.f ) ;
  441.     color( black ) ;
  442.     callobj( digit[value%10][0] ) ;
  443.     color( yellow ) ;
  444.     callobj( digit[value%10][1] ) ;
  445.     value /= 10 ;
  446.     translate( -12.f, 0.f, 0.f ) ;
  447.     bgnline() ;
  448.         vertex2f( 4.f, 0.f ) ;
  449.         vertex2f( 5.f, 0.f ) ;
  450.     endline() ;
  451.     translate( -12.f, 0.f, 0.f ) ;
  452.     for( i = 0 ; i < 3 ; i++ ) {
  453.         color( black ) ;
  454.         callobj( digit[value%10][0] ) ;
  455.         color( yellow ) ;
  456.         callobj( digit[value%10][1] ) ;
  457.         value /= 10 ;
  458.         translate( -12.f, 0.f, 0.f ) ;
  459.         }
  460.     popmatrix() ;
  461. #endif /* !defined( NETDEBUGGER ) */
  462. }
  463.  
  464.  
  465.  
  466. static void show_number(
  467.     int value,
  468.     int places,
  469.     float x,
  470.     float y,
  471.     Colorindex bg,
  472.     Colorindex fg
  473.     )
  474. {
  475. #if !defined( NETDEBUGGER )
  476.     int                i ;
  477.  
  478.     pushmatrix() ;
  479.     translate( x, y, 0.f ) ;
  480.     scale( digit_sx, digit_sy, 0.f ) ;
  481.     translate( 5.f + ( places - 1 ) * 12.f, 5.f, 0.f ) ;
  482.     for( i = 0 ; i < places ; i++ ) {
  483.         color( bg ) ;
  484.         callobj( digit[value%10][0] ) ;
  485.         color( fg ) ;
  486.         callobj( digit[value%10][1] ) ;
  487.         value /= 10 ;
  488.         translate( -12.f, 0.f, 0.f ) ;
  489.         }
  490.     popmatrix() ;
  491. #endif /* !defined( NETDEBUGGER ) */
  492. }
  493.  
  494.  
  495.  
  496. void show_score( void )
  497. {
  498.     if( db_base ) frontbuffer( 1 ) ;
  499.     show_something( FVPSCORE_L, FVPSCORE_B, FVPSCORE_R, FVPSCORE_T,
  500.                     _ABS( player[SELF].score ), 5,
  501.                     black, ( ( player[SELF].score >= 0 ) ? yellow : red ) ) ;
  502.     if( db_base ) frontbuffer( 0 ) ;
  503. }
  504.  
  505.  
  506.  
  507. static void show_something(
  508.     float l,
  509.     float b,
  510.     float r,
  511.     float t,
  512.     int value,
  513.     int places,
  514.     Colorindex bg,
  515.     Colorindex fg
  516.     )
  517. {
  518.     color( black );
  519.     sboxf( l, b, r, t ) ;
  520.     show_number( value, places, l, b, bg, fg ) ;
  521. }
  522.  
  523.  
  524.  
  525. void show_level( void )
  526. {
  527.     if( db_base ) frontbuffer(1);
  528.     show_something( FVPLEVEL_L, FVPLEVEL_B, FVPLEVEL_R, FVPLEVEL_T, 
  529.                     level, 3, black, yellow ) ;
  530.     if( db_base ) frontbuffer(0);
  531. }
  532.  
  533.  
  534.  
  535. void show_players( void )
  536. {
  537.     if( db_base ) frontbuffer(1);
  538.     show_something( FVPNOPLY_L, FVPNOPLY_B, FVPNOPLY_R, FVPNOPLY_T,
  539.                     number_players, 2, black, yellow ) ;
  540.     if( db_base ) frontbuffer(0);
  541. }
  542.  
  543.  
  544.  
  545. void post_new_message(
  546.     int count,
  547.     int vocal,
  548.     char *fmt,
  549.     ...
  550.     )
  551. {
  552. #if !defined( NETDEBUGGER )
  553.     va_list            args ;
  554.     int                nc_seen ;
  555.     int                i ;
  556.  
  557.     va_start( args, fmt ) ;
  558.     vsprintf( msgs, fmt, args ) ;
  559.  
  560.     nc_seen = (int)( VPMESGS_R - VPMESGS_L ) / (int)char_width ;
  561.  
  562.     if( strlen( msgs ) > nc_seen ) {
  563.         for( i = nc_seen ; i > 0 && msgs[i] != ' ' ; )
  564.             i-- ;
  565.         if( i > 0 && strlen( msgs+i ) <= nc_seen ) {
  566.             bulletin_line = ( bulletin_line + max_msg_lines - 1 )
  567.                           % max_msg_lines ;
  568.             strncpy( bulletin[bulletin_line], msgs, i ) ;
  569.             bulletin[bulletin_line][i] = '\0' ;
  570.             bulletin_color[bulletin_line] = current_bulletin_color ;
  571.             }
  572.         else {
  573.             i = nc_seen ;
  574.             bulletin_line = ( bulletin_line + max_msg_lines - 1 )
  575.                           % max_msg_lines ;
  576.             strncpy( bulletin[bulletin_line], msgs, i ) ;
  577.             bulletin[bulletin_line][i] = '\0' ;
  578.             bulletin_color[bulletin_line] = current_bulletin_color ;
  579.             }
  580.         bulletin_line = ( bulletin_line + max_msg_lines - 1 )
  581.                       % max_msg_lines ;
  582.         strncpy( bulletin[bulletin_line], &msgs[i], POST_MSG_SIZE ) ;
  583.         bulletin_color[bulletin_line] = current_bulletin_color ;
  584.         msg_redraw = 1 ;
  585.         }
  586.     else {
  587.         if( strcmp( msgs, bulletin[bulletin_line] ) ) {
  588.             bulletin_line = ( bulletin_line + max_msg_lines - 1 )
  589.                           % max_msg_lines ;
  590.             strncpy( bulletin[bulletin_line], msgs, POST_MSG_SIZE ) ;
  591.             bulletin_color[bulletin_line] = current_bulletin_color ;
  592.             msg_redraw = 1 ;
  593.             }
  594.         }
  595.     current_bulletin_color = green ;
  596.  
  597.     msg_count = ( count == 0 ) ? POST_MSG_DURATION : count ;
  598.     need_to_show_msgs = TRUE ;
  599.     need_to_show_msgs_vocal = vocal ;
  600. #else
  601.     va_list            args ;
  602.     struct BzNotice    note ;
  603.  
  604.     va_start( args, fmt ) ;
  605.     print_to_net_debugger( fmt, args ) ;
  606. #endif /* !defined( NETDEBUGGER ) */
  607.     va_end( args ) ;
  608. }
  609.  
  610.  
  611.  
  612. void print_to_net_debugger(
  613.     char *fmt,
  614.     va_list    args
  615.     )
  616. {
  617.     struct BzNotice    note ;
  618.     int                i ;
  619.  
  620.     vsprintf( msgs, fmt, args ) ;
  621.     i = strlen( msgs ) ;
  622.     if( i > sizeof( msgs ) ) {
  623.         msgs[sizeof(msgs)-1] = '\0' ;
  624.         }
  625.     else if( msgs[i-1] == '\n' ) {
  626.         msgs[i-1] = '\0' ;
  627.         }
  628.     note.bz_id = BZMSG ;
  629.     note.id = player[SELF].id ;
  630.     strncpy( note.out_message, msgs, MAIL_MSG_SIZE ) ;
  631.     send_out( ¬e, sizeof( note ) ) ;
  632. }
  633.  
  634.  
  635.  
  636. void show_msgs(
  637.     int vocal,
  638.     int redraw
  639.     )
  640. {
  641.     unsigned int    i ;
  642.     unsigned int    n ;
  643.     float x, y ;
  644.  
  645.     if( redraw ) {
  646.         if( db_base ) frontbuffer( 1 ) ;
  647.         color( black ) ;
  648.         sboxf( FVPMESGS_L, FVPMESGS_B, FVPMESGS_R, FVPMESGS_T ) ;
  649.         x = FVPMESGS_L + char_width / 2.f ;
  650.         y = FVPMESGS_B + ( FVPMESGS_T - FVPMESGS_B -
  651.                 ( max_msg_lines - .33f ) * char_height ) / 2.f ;
  652.         for( i = 0 ; i < max_msg_lines ; i++ ) { 
  653.             n = ( bulletin_line + i ) % max_msg_lines ;
  654.             color( bulletin_color[n] ) ;
  655.             cmov2( x, y ) ;
  656.             charstr( bulletin[n] ) ;
  657.             y+= char_height ;
  658.             }
  659.         if( db_base ) frontbuffer(0) ;
  660.         }
  661.  
  662.     if( vocal ) ringbell() ;
  663. }
  664.  
  665.  
  666.  
  667. void show_lives( void )
  668. {
  669.     if( db_base ) frontbuffer(1);
  670.     show_something( FVPLIVES_L, FVPLIVES_B, FVPLIVES_R, FVPLIVES_T,
  671.                     lives, 3, black, yellow ) ;
  672.     if( db_base ) frontbuffer(0);
  673. }
  674.  
  675.  
  676.  
  677. static void show_speed_util(
  678.     float track,
  679.     float l,
  680.     float b,
  681.     float r,
  682.     float t
  683.     )
  684. {
  685.     float            s ;
  686.  
  687.     if( !guiding ) {
  688.         if( track > 0.0f ) {
  689.             color( green ) ;
  690.             s = track ;
  691.             }
  692.         else if( track < 0.0f ) {
  693.             color( red ) ;
  694.             s = -track ;
  695.             }
  696.         else {
  697.             color( black ) ;
  698.             s = 0.0f ;
  699.             }
  700.         s = b + ( t - b ) * ( s / top_speed ) ;
  701.         sboxf( l, b, r, s ) ;
  702.         color( black ) ;
  703.         sboxf( l, s, r, t ) ;
  704.         }
  705.     else {
  706.         color( green );
  707.         sboxf( l, b, r, t ) ;
  708.         }
  709. }
  710.  
  711.  
  712.  
  713. void show_speed( void )
  714. {
  715.     show_speed_util( right_track, FVPRIGHT_L, FVPRIGHT_B, FVPRIGHT_R,
  716.                      FVPRIGHT_T ) ;
  717.     show_speed_util( left_track, FVPLEFTT_L, FVPLEFTT_B, FVPLEFTT_R,
  718.                      FVPLEFTT_T ) ;
  719. }
  720.  
  721.  
  722.  
  723. void show_gun_status(
  724.     int n
  725.     )
  726. {
  727.     char            *s ;
  728.     int                l ;
  729.     float            x ;
  730.     float            y ;
  731.  
  732.     if( IS_DEAD( player[SELF] ) ) {
  733.         if( sending_msg != SENDING_NO_MAIL ) {
  734.             n = MAIL_MSG_SIZE - strlen( mail.out_message ) ;
  735.             s = "MAILING" ;
  736.             l = 7 ;
  737.             }
  738.         else {
  739.             n = player[SELF].status - MIN_DEAD_STATUS + 1 ;
  740.             s = "DEAD" ;
  741.             l = 4 ;
  742.             }
  743.         }
  744.     else {
  745.         l = 7 ;
  746.         if( view_only ) {
  747.             s = "VIEWING" ;
  748.             n = 1 ;
  749.             }
  750.         else {
  751.             s = "LOADING" ;
  752.             }
  753.         }
  754.  
  755.     if( n > 0 ) {
  756.         x = ( FVPLOADM_R - FVPLOADM_L - l * char_width ) * 0.5f ;
  757.         y = ( FVPLOADM_T - FVPLOADM_B - .6f * char_height ) * 0.5f ;
  758.         show_something( FVPREADY_L, FVPREADY_B, FVPREADY_R, FVPREADY_T,
  759.                         n, 5, black, yellow ) ;
  760.         color( ( ( n / 5 ) % 2 ) ? red : black ) ;
  761.         sboxf( FVPLOADM_L, FVPLOADM_B, FVPLOADM_R, FVPLOADM_T ) ;
  762.         cmov2( FVPLOADM_L + x, FVPLOADM_B + y ) ;
  763.         color( ( ( n / 5 ) % 2 ) ? black : red ) ;
  764.         charstr( s ) ;
  765.         }
  766.     else {
  767.         x = ( FVPLOADM_R - FVPLOADM_L - 5.f * char_width ) * 0.5f ;
  768.         y = ( FVPLOADM_T - FVPLOADM_B - .6f * char_height ) * 0.5f ;
  769.         color( green ) ;
  770.         sboxf( FVPLOADM_L, FVPLOADM_B, FVPLOADM_R, FVPLOADM_T ) ;
  771.         sboxf( FVPREADY_L, FVPREADY_B, FVPREADY_R, FVPREADY_T ) ;
  772.         cmov2( FVPLOADM_L + x, FVPLOADM_B + y ) ;
  773.         color( black ) ;
  774.         charstr( "READY" ) ;
  775.         cmov2( FVPREADY_L + x, FVPREADY_B + y ) ;
  776.         charstr( "READY" ) ;
  777.         }
  778. }
  779.  
  780.  
  781.  
  782. static void title(
  783.     int left,
  784.     int bottom,
  785.     int right,
  786.     char *s
  787.     )
  788. {
  789.     float    x;
  790.  
  791.     x = (float)( left + right - strlen(s)*char_width ) / 2.f ;
  792.     color( black ) ;
  793.     cmov2( x+2.f, bottom-9.f-17.f) ;
  794.     charstr( s ) ;
  795.     color( ramp3 ) ;
  796.     cmov2( x, bottom-9.f-16.f ) ;
  797.     charstr( s ) ;
  798. }
  799.  
  800.  
  801.  
  802. void show_out_message( void )
  803. {
  804.     int                nc_seen ;
  805.     int                nc_total ;
  806.  
  807.     if( !solo && !view_only ) {
  808.         nc_seen = (int)( VPOUTMS_R - VPOUTMS_L ) / (int)char_width - 1 ;
  809.         if( db_base ) frontbuffer( 1 ) ;
  810.         color( black ) ;
  811.         sboxf( FVPOUTMS_L, FVPOUTMS_B, FVPOUTMS_R, FVPOUTMS_T ) ;
  812.         if( sending_msg == SENDING_ALL_MAIL ||
  813.             player[SELF].team == NEUTRAL_TEAM ) {
  814.             color( green ) ;
  815.             }
  816.         else if( player[SELF].team == RED_TEAM ) {
  817.             color( red ) ;
  818.             }
  819.         else if( player[SELF].team == BLUE_TEAM ) {
  820.             color( blue ) ;
  821.             }
  822.         else {    /* Shouldn't get here! */
  823.             color( green ) ;
  824.             }
  825.         cmov2( FVPOUTMS_L + 3.f, FVPOUTMS_B + 3.f) ;
  826.         if( ( nc_total = strlen( mail.out_message ) ) > nc_seen )
  827.             charstr( &mail.out_message[nc_total-nc_seen] ) ;
  828.         else
  829.             charstr( mail.out_message ) ;
  830.         if( sending_msg != SENDING_NO_MAIL )
  831.             charstr( "_" ) ;
  832.         if( db_base ) frontbuffer( 0 ) ;
  833.         }
  834. }
  835.  
  836.  
  837.  
  838.  
  839. void show_zoom_factor( void )
  840. {
  841.     short            l ;
  842.     short            r ;
  843.     short            b ;
  844.     short            t ;
  845.     float            xmax ;
  846.     float            ymax ;
  847.     char            mag_power[5] ;
  848.  
  849.     if( ol_mode > -1 ) {
  850.         reshapeviewport() ;
  851.         getviewport( &l, &r, &b, &t ) ;
  852.         xmax = r - l ;
  853.         ymax = t - b ;
  854.         loadmatrix( id_mat ) ;
  855.         ortho2( 0.f, xmax, 0.f, ymax ) ;
  856.         color( 1 ) ;
  857.         sboxf( 0.f, 0.f, 5.f * char_width, char_height + 4.f ) ;
  858.         color( 2 ) ;
  859.         cmov2( 3.f, 3.f ) ;
  860.         sprintf( mag_power, "X%-3g", zoom_factor ) ;
  861.         charstr( mag_power ) ;
  862.         }
  863. }
  864.  
  865.  
  866.  
  867. void drawOverlay( void )
  868. {
  869.     reshapeviewport() ;
  870.     color( 0 ) ;
  871.     clear() ;
  872.  
  873.     if( ol_mode > -1 ) {
  874.         pushmatrix();
  875.         loadmatrix( id_mat ) ;
  876.         ortho2(-825.f,825.f,-825.f,825.f);
  877.         callobj( radar1 ) ;
  878.         popmatrix();
  879.         show_zoom_factor() ;
  880.         }
  881.  
  882.     if( ol_mode == 1 ) {
  883.         show_pick_tank_instructions() ;
  884.         }
  885. }
  886.  
  887.  
  888.  
  889. static void show_pick_tank_instructions( void )
  890. {
  891.     short            l ;
  892.     short            r ;
  893.     short            b ;
  894.     short            t ;
  895.     float            x ;
  896.     float            y ;
  897.     float            xmax ;
  898.     float            ymax ;
  899.  
  900.     reshapeviewport() ;
  901.     getviewport( &l, &r, &b, &t ) ;
  902.     xmax = r - l ;
  903.     ymax = t - b ;
  904.     loadmatrix( id_mat ) ;
  905.     ortho2( 0.f, xmax, 0.f, ymax ) ;
  906.     y = ymax - 60.f ;
  907.     x = ( xmax - 25.f * char_width ) / 2.f ;
  908.     cmov2( x, y ) ;
  909.     color( 2 ) ;
  910.  
  911.     if( picking_tank ) {
  912.         charstr("Hit the following keys to");
  913.         cmov2(x, (y -= char_height)) ;
  914.         if( !init_wait )
  915.             charstr("change tanks:");
  916.         else
  917.             charstr( "select your tank:" ) ;
  918.         cmov2( x, ( y -= char_height*1.25f ) ) ;
  919.         charstr( "1 regular          50 pts" ) ;
  920.         cmov2( x, ( y -= char_height) ) ;
  921.         charstr( "2 super            75 pts" ) ;
  922.         cmov2( x, ( y -= char_height) ) ;
  923.         charstr( "3 stealth         100 pts" ) ;
  924.         cmov2( x, ( y -= char_height) ) ;
  925.         charstr( "4 runner          125 pts" ) ;
  926.         }
  927.     else if( !solo ) {
  928.         charstr("    Available options:");
  929.         cmov2(x, (y -= char_height*1.25f)) ;
  930.         if( player[SELF].team == NEUTRAL_TEAM )  {
  931.             charstr("  b : join blue team");
  932.             cmov2(x, (y -= char_height)) ;
  933.             }
  934.         charstr("  c : change tanks");
  935.         cmov2(x, (y -= char_height)) ;
  936.         charstr("  m : mail message");
  937.         cmov2(x, (y -= char_height)) ;
  938.         if( player[SELF].team == NEUTRAL_TEAM )  {
  939.             charstr("  r : join red team");
  940.             cmov2(x, (y -= char_height)) ;
  941.             }
  942.         charstr("  t : mail team message");
  943.         }
  944. }
  945.  
  946.  
  947.  
  948. void drawBaseCB(
  949.     Widget w,
  950.     XtPointer client_data,
  951.     XtPointer call_data
  952.     )
  953. {
  954.     GLXwinset( XtDisplay(w), ((GlxDrawCallbackStruct *)call_data)->window ) ;
  955.     redraw_base_screen() ;
  956. }
  957.  
  958.  
  959.  
  960. void drawRadarCB(
  961.     Widget w,
  962.     XtPointer client_data,
  963.     XtPointer call_data
  964.     )
  965. {
  966.     GLXwinset( XtDisplay(w), ((GlxDrawCallbackStruct *)call_data)->window ) ;
  967.     if( init_wait ) {
  968.         reshapeviewport() ;
  969.         color( black ) ;
  970.         clear() ;
  971.         }
  972.     else {
  973.         radar_view() ;
  974.         }
  975.     gflush() ;
  976.     swapbuffers() ;
  977.     GLXwinset( display, base_window ) ;
  978. }
  979.  
  980.  
  981.  
  982. void initBaseGlCB(
  983.     Widget w,
  984.     XtPointer client_data,
  985.     XtPointer call_data )
  986. {
  987. #if !defined( NETDEBUGGER )
  988.     int                    n ;
  989.     Dimension            wi, hi ;
  990.     Dimension            x, y ;
  991.  
  992.     base_window = ((GlxDrawCallbackStruct *)call_data)->window ;
  993.     GLXwinset( XtDisplay(w), base_window ) ;
  994.  
  995.     n = 0 ;
  996.     XtSetArg( wargs[n], XmNwidth, &wi ) ; n++ ;
  997.     XtSetArg( wargs[n], XmNheight, &hi ) ; n++ ;
  998.     XtSetArg( wargs[n], XmNx, &x ) ; n++ ;
  999.     XtSetArg( wargs[n], XmNy, &y ) ; n++ ;
  1000.     XtGetValues( w, wargs, n ) ;
  1001.  
  1002.     zbuffer( FALSE ) ;
  1003.     subpixel( TRUE ) ;
  1004.     mmode( MVIEWING ) ;
  1005.     loadmatrix( id_mat ) ;
  1006.     concave( FALSE ) ;
  1007.     backface( FALSE ) ;
  1008.     init_color( BASE_VIEW_MAP, w ) ;
  1009.     indicate_map_order( base_window, BASE_VIEW_MAP ) ;
  1010.  
  1011.     current_bulletin_color = green ;
  1012.     teamColor[NEUTRAL_TEAM] = green ;
  1013.     teamColor[RED_TEAM]     = red ;
  1014.     teamColor[BLUE_TEAM]    = blue ;
  1015.  
  1016.     make_all() ;
  1017.  
  1018.     init_var() ;
  1019.     init_bulletin() ;
  1020. #endif /* !defined( NETDEBUGGER ) */
  1021. }
  1022.  
  1023.  
  1024.  
  1025. void initRadarGlCB(
  1026.     Widget w,
  1027.     XtPointer client_data,
  1028.     XtPointer call_data )
  1029. {
  1030. #if !defined( NETDEBUGGER )
  1031.     int                n ;
  1032.     Dimension        x, y ;
  1033.     Dimension        wi, hi ;
  1034.  
  1035.     radar_window = ((GlxDrawCallbackStruct *)call_data)->window ;
  1036.     GLXwinset( XtDisplay(w), radar_window ) ;
  1037.  
  1038.     n = 0 ;
  1039.     XtSetArg( wargs[n], XmNwidth, &wi ) ; n++ ;
  1040.     XtSetArg( wargs[n], XmNheight, &hi ) ; n++ ;
  1041.     XtSetArg( wargs[n], XmNx, &x ) ; n++ ;
  1042.     XtSetArg( wargs[n], XmNy, &y ) ; n++ ;
  1043.     XtSetArg( wargs[n], ( use_pups ) ? GlxNpopupWindow : GlxNoverlayWindow,
  1044.          &radar_ol_window ); n++ ;
  1045.     XtGetValues( w, wargs, n ) ;
  1046.  
  1047.     zbuffer( FALSE ) ;
  1048.     subpixel( TRUE ) ;
  1049.     shademodel( FLAT ) ;
  1050.     mmode( MVIEWING ) ;
  1051.     loadmatrix( id_mat ) ;
  1052.     concave( FALSE ) ;
  1053.     backface( FALSE ) ;
  1054.     init_color( RADAR_VIEW_MAP, w ) ;
  1055.     indicate_map_order( radar_window, RADAR_VIEW_MAP ) ;
  1056.  
  1057.     GLXwinset( XtDisplay(w), radar_ol_window ) ;
  1058.     init_overlay_color( w ) ;
  1059.     make_radar() ;
  1060. #endif /* !defined( NETDEBUGGER ) */
  1061. }
  1062.  
  1063.  
  1064.  
  1065. /*------------------------------------------------------------------------------
  1066.  * Set the bulletin color for the next posted message.
  1067.  *----------------------------------------------------------------------------*/
  1068. void set_bulletin_color(
  1069.     Colorindex n
  1070.     )
  1071. {
  1072.     current_bulletin_color = n ;
  1073. }
  1074.  
  1075.  
  1076.  
  1077. float radar_view_angle[3][2] = {
  1078.     { -375., 750. },
  1079.     {    0.,   0. },
  1080.     {  375., 750. }
  1081.     } ;
  1082. float binocular_radar_view_angle[3][2] = {
  1083.     { -375., 750. },
  1084.     {    0.,   0. },
  1085.     {  375., 750. }
  1086.     } ;
  1087. static float radar_north[4][2] = {
  1088.     { -25., 650. },
  1089.     { -25., 700. },
  1090.     {  25., 650. },
  1091.     {  25., 700. },
  1092.     } ;
  1093.  
  1094.  
  1095. void radar_view( void )
  1096. {
  1097.     unsigned            i;
  1098.  
  1099.     reshapeviewport() ;
  1100.  
  1101.     loadmatrix( id_mat ) ;
  1102.     pushmatrix();
  1103.     ortho2( -1650.f, 1650.f, -1650.f, 1650.f ) ;
  1104.     scale( zoom_factor, zoom_factor, 0.f ) ;
  1105.  
  1106.     color( black ) ;
  1107.     clear() ;
  1108.     font( 1 ) ;
  1109.  
  1110.     if( zoom_factor > 2.f ) {
  1111.         color( yellow ) ;
  1112.         rect( -5.f, -10.f, 5.f, 10.f ) ;
  1113.         }
  1114.  
  1115.     rot( player[SELF].head, 'z' );
  1116.     translate( -player[SELF].x, -player[SELF].y, 0.f ) ;
  1117.     color( ground_color ) ;
  1118.     callobj( border ) ;
  1119.     if( show_flags ) {
  1120.         callobj( flag_homes ) ;
  1121.         if( !red_flag_held ) {
  1122.             color( red ) ;
  1123.             pnt2( flag_x[RED_FLAG], flag_y[RED_FLAG] ) ;
  1124.             }
  1125.         if( !blue_flag_held ) {
  1126.             color( blue ) ;
  1127.             pnt2( flag_x[BLUE_FLAG], flag_y[BLUE_FLAG] ) ;
  1128.             }
  1129.         }
  1130.  
  1131.     for(i = ENEMY ; i < number_players ; i++ ) {
  1132.         color( teamColor[player[i].team] ) ;
  1133.         if( IS_ALIVE( player[i] ) ) {
  1134.             if( !IS_STEALTH_TANK( player[i] ) ) {
  1135.                 pushmatrix() ;
  1136.                 translate( player[i].x, player[i].y, 0.f ) ;
  1137.                 rot( -player[i].head, 'z' ) ;
  1138.                 rectf( -5.f, -10.f, 5.f, 10.f ) ;
  1139.                 popmatrix() ;
  1140.                 }
  1141.             }
  1142.         else {
  1143.             pnt2(player[i].x,player[i].y);
  1144.             }
  1145.         }
  1146.  
  1147.     color( white ) ;
  1148.     for( i = SELF ; i < number_players ; i++ ) {
  1149.         if( player[i].msl_status > 0 ) {
  1150.             cmov2( player[i].msl_x, player[i].msl_y ) ;
  1151.             charstr("+");
  1152.             }
  1153.         }
  1154.  
  1155.     color( ground_color ) ;
  1156.     for( i = CONES ; i < TOTALOBSTS ; i++ ) {
  1157.         rectf( obst_x[i]-10.f, obst_y[i]-10.f, obst_x[i]+10.f, obst_y[i]+10.f );
  1158.         }
  1159.  
  1160.     if( mine_status > 0 ) {
  1161.         color( yellow );
  1162.         circ( mine_x, mine_y, 15.f ) ;
  1163.         if( !perm_mine )
  1164.             circ( mine_x, mine_y, DET_MINE_RADIUS ) ;
  1165.         }
  1166.  
  1167.     font( 0 ) ;
  1168.     popmatrix() ;
  1169.  
  1170.     ortho2(-825.f,825.f,-825.f,825.f) ;
  1171.  
  1172.     color( yellow );
  1173.     bgnline() ;
  1174.         if( binoculars ) {
  1175.             v2f( binocular_radar_view_angle[0] ) ;
  1176.             v2f( binocular_radar_view_angle[1] ) ;
  1177.             v2f( binocular_radar_view_angle[2] ) ;
  1178.             }
  1179.         else {
  1180.             v2f( radar_view_angle[0] ) ;
  1181.             v2f( radar_view_angle[1] ) ;
  1182.             v2f( radar_view_angle[2] ) ;
  1183.             }
  1184.     endline() ;
  1185.  
  1186.     rot( player[SELF].head, 'z' );
  1187.  
  1188.     color( yellow );
  1189.     bgnline() ;
  1190.         v2f( radar_north[0] ) ;
  1191.         v2f( radar_north[1] ) ;
  1192.         v2f( radar_north[2] ) ;
  1193.         v2f( radar_north[3] ) ;
  1194.     endline() ;
  1195. }
  1196.  
  1197.  
  1198.  
  1199. static void init_bulletin( void )
  1200. {
  1201.     max_msg_lines = (int)( VPMESGS_T - VPMESGS_B ) / (int)char_height ;
  1202.  
  1203.     if( ( bulletin_color = (Colorindex *)
  1204.             calloc( max_msg_lines, sizeof( Colorindex ) ) ) == NULL ) {
  1205.         fprintf( stderr, "%s: out of memory\n", basename ) ;
  1206.         end_program( 1 ) ;
  1207.         }
  1208.  
  1209.     if( ( bulletin = (BulletinLine *)
  1210.             calloc( max_msg_lines, sizeof( BulletinLine ) ) ) == NULL ) {
  1211.         fprintf( stderr, "%s: out of memory\n", basename ) ;
  1212.         end_program( 1 ) ;
  1213.         }
  1214. }
  1215.