Back to index

extremetuxracer  0.5beta
course_mgr.cpp
Go to the documentation of this file.
00001 /* 
00002  * PPRacer 
00003  * Copyright (C) 2004-2005 Volker Stroebel <volker@planetpenguin.de>
00004  *
00005  * Copyright (C) 1999-2001 Jasmin F. Patry
00006  * 
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  * 
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  * 
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00020  */
00021 
00022 #include "course_mgr.h"
00023 #include "tcl_util.h"
00024 #include "textures.h"
00025 
00026 #include "game_mgr.h"
00027 
00028 static char err_buff[BUFF_LEN];
00029 
00030 static bool initialized = false;   /* has module been initialized? */
00031 
00032 std::list<CourseData> openCourseList;     /* list of open courses */
00033 std::list<EventData> eventList;           /* list of events */
00034 
00035 
00036 
00037 static char *race_condition_names[RACE_CONDITIONS_NUM_CONDITIONS] =
00038 {
00039     "sunny",
00040     "cloudy",
00041     "night",
00042        "evening"
00043 };
00044 
00045 
00046 /*---------------------------------------------------------------------------*/
00054 void init_course_manager() 
00055 {
00056     check_assertion( initialized == false,
00057                    "Attempt to initialize course manager twice" );
00058 
00059     initialized = true;
00060 }
00061 
00062 /*---------------------------------------------------------------------------*/
00069 CourseData* create_open_course_data( Tcl_Interp *ip, CONST84 char *string, 
00070                                         char **err_msg )
00071 {
00072     CONST84 char **argv = NULL;
00073     CONST84 char **orig_argv = NULL;
00074     int argc = 0;
00075     
00076     double par_time = 120;
00077 
00078     CourseData *open_course_data = new CourseData();
00079 
00080     if ( Tcl_SplitList( ip, string, &argc, &argv ) == TCL_ERROR ) {
00081               *err_msg = "open course data is not a list";
00082               goto bail_open_course_data;
00083     }
00084 
00085     orig_argv = argv;
00086 
00087     while ( *argv != NULL ) {
00088        if ( strcmp( *argv, "-course" ) == 0 ) {
00089            NEXT_ARG;
00090 
00091            if ( *argv == NULL ) {
00092               *err_msg = "No data supplied for -course in open course data";
00093               goto bail_open_course_data;
00094            }
00095 
00096            open_course_data->course = *argv; //string_copy( *argv );
00097        } else if ( strcmp( *argv, "-name" ) == 0 ) {
00098            NEXT_ARG;
00099 
00100            if ( *argv == NULL ) {
00101               *err_msg = "No data supplied for -name in open course data";
00102               goto bail_open_course_data;
00103            }
00104 
00105            open_course_data->name = *argv; //string_copy( *argv );
00106        } else if ( strcmp( *argv, "-description" ) == 0 ) {
00107            NEXT_ARG;
00108 
00109            if ( *argv == NULL ) {
00110               *err_msg = "No data supplied for -description in open course data";
00111               goto bail_open_course_data;
00112            }
00113 
00114            open_course_data->description = *argv; //string_copy( *argv );
00115        } else if ( strcmp( *argv, "-contributed" ) == 0 ) {
00116            NEXT_ARG;
00117 
00118            if ( *argv == NULL ) {
00119               *err_msg = "No data supplied for -contributed in open course data";
00120               goto bail_open_course_data;
00121            }
00122 
00123            open_course_data->contributed = *argv; //string_copy( *argv );
00124        }else if ( strcmp( *argv, "-par_time" ) == 0 ) {
00125            NEXT_ARG;
00126 
00127            if ( *argv == NULL ) {
00128               par_time = 120.0;
00129               print_warning( PEDANTIC_WARNING,
00130                             "No data supplied for -par_time in open course "
00131                             "data.  Using %g seconds.", par_time );
00132            } else if ( Tcl_GetDouble( ip, *argv, &par_time ) != TCL_OK ) {
00133               *err_msg = "Invalid value for -par_time in open course data";
00134               goto bail_open_course_data;
00135            }
00136        } else {
00137            sprintf( err_buff, "unrecognized option `%s' in open course data",
00138                    *argv );
00139            *err_msg = err_buff;
00140            goto bail_open_course_data;
00141        }
00142 
00143        NEXT_ARG;
00144     }
00145 
00146     /* Check mandatory arguments */
00147     if ( open_course_data->course.empty() ) {
00148               *err_msg = "No course specified in open course data";
00149               goto bail_open_course_data;
00150     }
00151 
00152     if ( open_course_data->name.empty() ) {
00153               *err_msg = "No name specified in open course data";
00154               goto bail_open_course_data;
00155     }
00156 
00157     open_course_data->par_time = par_time;
00158 
00159     Tcl_Free( (char*) orig_argv );
00160 
00161     return open_course_data;
00162 
00163 bail_open_course_data:
00164 
00165     if ( orig_argv ) {
00166        Tcl_Free( (char*) orig_argv );
00167     }
00168 
00169     if ( open_course_data ) {
00170               delete open_course_data;
00171     }
00172 
00173     return NULL;
00174 }
00175 
00176 /*---------------------------------------------------------------------------*/
00183 static int open_courses_cb( ClientData cd, Tcl_Interp *ip,
00184                          int argc, CONST84 char **argv )
00185 {
00186     char *err_msg;
00187     CONST84 char **list = NULL;
00188     int num_courses;
00189     std::list<CourseData>::iterator lastElem;
00190     int i;
00191        
00192        check_assertion( initialized,
00193                    "course_mgr module not initialized" );
00194 
00195     if ( argc != 2 ) {
00196               err_msg = "Wrong number of arguments";
00197               goto bail_open_courses;
00198     }
00199 
00200     if ( Tcl_SplitList( ip, argv[1], &num_courses, &list ) == TCL_ERROR ) {
00201               err_msg = "Argument is not a list";
00202               goto bail_open_courses;
00203     }
00204 
00205     /* Add items to end of list */
00206     lastElem = openCourseList.end();
00207 
00208     for ( i=0; i<num_courses; i++ ) {
00209               CourseData *data;
00210               data = create_open_course_data( ip, list[i], &err_msg );
00211 
00212               if ( data == NULL ) {
00213               goto bail_open_courses;
00214               }
00215 
00216               openCourseList.push_back(*data);
00217        }
00218 
00219     Tcl_Free( (char*) list );
00220     list = NULL;
00221 
00222     return TCL_OK;
00223 
00224 bail_open_courses:
00225 
00226     /* We'll leave the data that was successfully added in the list. */
00227 
00228     Tcl_AppendResult(
00229        ip,
00230        "Error in call to tux_open_courses: ", 
00231        err_msg,
00232        "\n",
00233        "Usage: tux_open_courses { list of open courses }",
00234        (NULL) );
00235     return TCL_ERROR;
00236 }
00237 
00238 
00239 /*---------------------------------------------------------------------------*/
00247 static
00248 CourseData* create_race_data ( Tcl_Interp *ip, CONST84 char *string, char **err_msg )
00249 {
00250        CONST84 char **argv = NULL;
00251     CONST84 char **orig_argv = NULL;
00252     int argc = 0;
00253 
00254     bool   herring_req_init = false;
00255     bool   time_req_init = false;
00256     bool   score_req_init = false;
00257 
00258     CourseData *race_data = new CourseData;
00259     
00260     race_data->snowtype = -1;
00261        
00262     if ( Tcl_SplitList( ip, string, &argc, &argv ) == TCL_ERROR ) {
00263               *err_msg = "race data is not a list";
00264               goto bail_race_data;
00265     }
00266 
00267     orig_argv = argv;
00268 
00269        
00270     while ( *argv != NULL ) {
00271        if ( strcmp( *argv, "-course" ) == 0 ) {
00272            NEXT_ARG;
00273            if ( *argv == NULL ) {
00274                      *err_msg = "No data supplied for -course in race data";
00275                      goto bail_race_data;
00276            }
00277            race_data->course = *argv; //string_copy( *argv );
00278 
00279        } else if ( strcmp( *argv, "-name" ) == 0 ) {
00280            NEXT_ARG;
00281 
00282            if ( *argv == NULL ) {
00283               *err_msg = "No data supplied for -name in race data";
00284               goto bail_race_data;
00285            }
00286 
00287            race_data->name = *argv; //string_copy( *argv );           
00288 
00289        } else if ( strcmp( *argv, "-description" ) == 0 ) {
00290            NEXT_ARG;
00291 
00292            if ( *argv == NULL ) {
00293               *err_msg = "No data supplied for -description in race data";
00294               goto bail_race_data;
00295            }
00296 
00297            race_data->description = *argv; //string_copy( *argv );
00298                           race_data->description = *argv; //string_copy( *argv );
00299 
00300       } else if ( strcmp( *argv, "-contributed" ) == 0 ) {
00301            NEXT_ARG;
00302 
00303           if ( *argv == NULL ) {
00304               *err_msg = "No data supplied for -contributed in race data";
00305               goto bail_race_data;
00306            }
00307 
00308            race_data->contributed = *argv; //string_copy( *argv );
00309        } else if ( strcmp( *argv, "-herring" ) == 0 ) {
00310            NEXT_ARG;
00311 
00312            if ( *argv == NULL ) {
00313               *err_msg = "No data supplied for -herring in race data";
00314               goto bail_race_data;
00315            }
00316 
00317            if ( get_tcl_int_tuple( 
00318               ip, *argv, race_data->herring_req, 
00319               sizeof(race_data->herring_req)/sizeof(race_data->herring_req[0]) ) == TCL_ERROR )
00320            {
00321               *err_msg = "Value for -herring is not a list or has "
00322                   "the wrong number of elements";
00323               goto bail_race_data;
00324            }
00325 
00326            herring_req_init = true;
00327 
00328        } else if ( strcmp( *argv, "-time" ) == 0 ) {
00329            NEXT_ARG;
00330 
00331            if ( *argv == NULL ) {
00332               *err_msg = "No data supplied for -time in race data" ;
00333               goto bail_race_data;
00334            }
00335 
00336            if ( get_tcl_tuple( ip, *argv, race_data->time_req, 
00337                             sizeof(race_data->time_req)/sizeof(race_data->time_req[0]) ) 
00338                == TCL_ERROR ) 
00339            {
00340               *err_msg = "Value for -time is not a list or hsa the "
00341                   "wrong number of elements";
00342               goto bail_race_data;
00343            }
00344 
00345            time_req_init = true;
00346        } else if ( strcmp( *argv, "-score" ) == 0 ) {
00347            NEXT_ARG;
00348 
00349            if ( *argv == NULL ) {
00350               *err_msg = "No data supplied for -score in race data";
00351               goto bail_race_data;
00352            }
00353 
00354            if ( get_tcl_tuple( ip, *argv, race_data->score_req,
00355                             sizeof(race_data->score_req)/sizeof(race_data->score_req[0]) )
00356                == TCL_ERROR ) 
00357            {
00358               *err_msg = "Value for -score is not a list or has the "
00359                   "wrong number of elements";
00360               goto bail_race_data;
00361            }
00362 
00363            score_req_init = true;
00364        } else if ( strcmp( *argv, "-mirrored" ) == 0 ) {
00365            NEXT_ARG;
00366 
00367            if ( *argv == NULL ) {
00368               *err_msg = "No data supplied for -mirrored in race data";
00369               goto bail_race_data;
00370            }
00371 
00372            if ( strcmp( *argv, "yes" ) == 0 ) {
00373                      race_data->mirrored = true;
00374            } else {
00375                      race_data->mirrored = false;
00376            }
00377     } else if ( strcmp( *argv, "-snowtype" ) == 0 ) {
00378            NEXT_ARG;
00379 
00380            if ( *argv == NULL ) {
00381               *err_msg = "No data supplied for -snowtype in race data";
00382               goto bail_race_data;
00383            }
00384         if ( Tcl_GetInt( ip, *argv, &(race_data->snowtype) ) != TCL_OK ) {
00385               *err_msg = "Invalid value for -snowtype in open course data";
00386               goto bail_race_data;
00387            }
00388     } else if ( strcmp( *argv, "-windtype" ) == 0 ) {
00389            NEXT_ARG;
00390 
00391            if ( *argv == NULL ) {
00392               *err_msg = "No data supplied for -windtype in race data";
00393               goto bail_race_data;
00394            }
00395         if ( Tcl_GetInt( ip, *argv, &(race_data->windtype) ) != TCL_OK ) {
00396               *err_msg = "Invalid value for -windtype in open course data";
00397               goto bail_race_data;
00398            }
00399        } else if ( strcmp( *argv, "-conditions" ) == 0 ) {
00400            int i;
00401            NEXT_ARG;
00402 
00403            if ( *argv == NULL ) {
00404               *err_msg = "No data supplied for -conditions in race data";
00405               goto bail_race_data;
00406            }
00407 
00408            for ( i=0; i<RACE_CONDITIONS_NUM_CONDITIONS; i++ ) {
00409               if ( strcmp( race_condition_names[i],
00410                                     *argv ) == 0 )
00411               {
00412                   break;
00413               }
00414            }
00415 
00416            if ( i == RACE_CONDITIONS_NUM_CONDITIONS ) {
00417               *err_msg = "Invalid value for -conditions in race data";
00418               goto bail_race_data;
00419            }
00420 
00421            race_data->condition = (race_conditions_t)i;
00422        } else if ( strcmp( *argv, "-windy" ) == 0 ) {
00423            NEXT_ARG;
00424 
00425            if ( *argv == NULL ) {
00426               *err_msg = "No data supplied for -windy in race data";
00427               goto bail_race_data;
00428            }
00429 
00430            if ( strcmp( *argv, "yes" ) == 0 ) {
00431                      race_data->windy = true;
00432            } else {
00433                      race_data->windy = false;
00434            }
00435        } else if ( strcmp( *argv, "-snowing" ) == 0 ) {
00436            NEXT_ARG;
00437 
00438            if ( *argv == NULL ) {
00439               *err_msg = "No data supplied for -snowing in race data";
00440               goto bail_race_data;
00441            }
00442 
00443            if ( strcmp( *argv, "yes" ) == 0 ) {
00444                      race_data->snowing = true;
00445            } else {
00446                      race_data->snowing = false;
00447            }
00448        } else {
00449            sprintf( err_buff, "unrecognized option `%s' in race data",
00450                    *argv );
00451            *err_msg = err_buff;
00452            goto bail_race_data;
00453        }
00454 
00455        NEXT_ARG;
00456     }
00457 
00458     /* Check mandatory arguments */
00459     if ( race_data->course.empty() ) {
00460               *err_msg = "No course specified in race data";
00461               goto bail_race_data;
00462     }
00463 
00464     if ( !herring_req_init ||
00465         !time_req_init ||
00466         !score_req_init ) 
00467     {
00468        *err_msg = "Must specify requirement for herring, time, and score.";
00469        goto bail_race_data;
00470     }
00471 
00472     Tcl_Free( (char*) orig_argv );
00473 
00474     return race_data;
00475 
00476 bail_race_data:
00477     if ( orig_argv ) {
00478        Tcl_Free( (char*) orig_argv );
00479     }
00480 
00481     if ( race_data ) {
00482        delete( race_data );
00483     }
00484 
00485     return NULL;
00486 }
00487 
00488 
00489 /*---------------------------------------------------------------------------*/
00497 static
00498 CupData* create_cup_data( Tcl_Interp *ip, CONST84 char *string, char **err_msg )
00499 {
00500     CONST84 char **argv = NULL;
00501     CONST84 char **orig_argv = NULL;
00502     int argc = 0;
00503 
00504     std::list<CourseData> raceList;
00505     CONST84 char **races = NULL;
00506     int num_races = 0;
00507     int i;
00508 
00509     CupData* cup_data = new CupData();
00510 
00511     if ( Tcl_SplitList( ip, string, &argc, &argv ) == TCL_ERROR ) {
00512               *err_msg = "cup data is not a list";
00513               goto bail_cup_data;
00514     }
00515     orig_argv = argv;
00516 
00517     while ( *argv != NULL ) {
00518        if ( strcmp( *argv, "-name" ) == 0 ) {
00519            NEXT_ARG;
00520 
00521            if ( *argv == NULL ) {
00522               *err_msg = "No data supplied for -name in cup data";
00523               goto bail_cup_data;
00524            }
00525            cup_data->name = *argv; //string_copy( *argv );
00526        } else if ( strcmp( *argv, "-icon" ) == 0 ) {
00527            NEXT_ARG;
00528            if ( *argv == NULL ) {
00529               *err_msg = "No data supplied for -icon in cup data";
00530               goto bail_cup_data;
00531            }
00532 
00533            cup_data->icon = *argv; //string_copy( *argv );
00534        } else if ( strcmp( *argv, "-races" ) == 0 ) {
00535            NEXT_ARG;
00536            if ( *argv == NULL ) {
00537               *err_msg= "No data supplied for -races in cup data";
00538               goto bail_cup_data;
00539            }
00540 
00541            if ( Tcl_SplitList( ip, *argv, &num_races, &races ) == TCL_ERROR ) {
00542               *err_msg = "Race data is not a list in event data";
00543               goto bail_cup_data;
00544            }
00545            for ( i=0; i<num_races; i++) {
00546               CourseData *raceData;
00547                      raceData = create_race_data( ip, races[i], err_msg );
00548                             
00549               if ( raceData == NULL ) {
00550                   goto bail_cup_data;
00551               }
00552               raceList.push_back(*raceData);
00553            }
00554 
00555            Tcl_Free( (char*) races );
00556            races = NULL;
00557        } else {
00558            sprintf( err_buff, "Unrecognized argument `%s'", *argv );
00559            *err_msg = err_buff;
00560            goto bail_cup_data;
00561        }
00562 
00563        NEXT_ARG;
00564     }
00565 
00566     /* Make sure mandatory fields have been specified */
00567     if ( cup_data->name.empty() ) {
00568        *err_msg = "Must specify a name in cup data";
00569        goto bail_cup_data;
00570     }
00571 
00572     if ( cup_data->icon.empty() ) {
00573        *err_msg = "Must specify an icon texture in cup data";
00574        goto bail_cup_data;
00575     }
00576 
00577     if ( raceList.empty() ) {
00578               *err_msg = "Must specify a race list in cup data";
00579               goto bail_cup_data;
00580     }
00581 
00582     /* Create a new cup data object */
00583     check_assertion( cup_data != NULL, "out of memory" );
00584 
00585     cup_data->raceList = raceList;
00586     bind_texture( cup_data->name.c_str(), cup_data->icon.c_str() );
00587 
00588     Tcl_Free( (char*) orig_argv );
00589     argv = NULL;
00590 
00591     return cup_data;
00592 
00593 bail_cup_data:
00594 
00595     if ( orig_argv ) {
00596        Tcl_Free( (char*) orig_argv );
00597     }
00598 
00599 /*    if ( name ) {
00600        free( name );
00601     }
00602 
00603     if ( icon ) {
00604        free( icon );
00605     }
00606 */
00607     if ( races ) {
00608        Tcl_Free( (char*) races );
00609     }
00610 
00611     /* Clean out race list */
00612    
00613     if ( cup_data ) {
00614               delete( cup_data );
00615     }
00616 
00617     return NULL;
00618 }
00619 
00620 /*---------------------------------------------------------------------------*/
00628 static
00629 EventData* create_event_data( Tcl_Interp *ip, CONST84 char *string, char **err_msg )
00630 {
00631     CONST84 char **orig_argv = NULL;
00632     CONST84 char **argv = NULL;
00633     int argc = 0;
00634 
00635     std::list<CupData> cupList;
00636     CONST84 char **cups = NULL;
00637     int num_cups = 0;
00638     int i;
00639 
00640     EventData* event_data = new EventData();
00641 
00642     if ( Tcl_SplitList( ip, string, &argc, &argv ) == TCL_ERROR ) {
00643        *err_msg = "event data is not a list";
00644        goto bail_event_data;
00645     }
00646 
00647     orig_argv = argv;
00648 
00649     while ( *argv != NULL ) {
00650        if ( strcmp( *argv, "-name" ) == 0 ) {
00651            NEXT_ARG;
00652 
00653            if ( *argv == NULL ) {
00654               *err_msg = "No data supplied for -name in event data";
00655               goto bail_event_data;
00656            }
00657 
00658            event_data->name = *argv;             //string_copy( *argv );
00659        } else if ( strcmp( *argv, "-icon" ) == 0 ) {
00660            NEXT_ARG;
00661 
00662            if ( *argv == NULL ) {
00663               *err_msg = "No data supplied for -icon in event data";
00664               goto bail_event_data;
00665            }
00666 
00667            event_data->icon = *argv; //string_copy( *argv );
00668        } else if ( strcmp( *argv, "-music" ) == 0 ) {
00669            NEXT_ARG;
00670 
00671            if ( *argv == NULL ) {
00672               *err_msg = "No data supplied for -music in event data";
00673               goto bail_event_data;
00674            }
00675 
00676            event_data->music = *argv; //string_copy( *argv );
00677        } else if ( strcmp( *argv, "-cups" ) == 0 ) {
00678            NEXT_ARG;
00679 
00680            if ( *argv == NULL ) {
00681               *err_msg = "No data supplied for -cups in event data";
00682               goto bail_event_data;
00683            }
00684 
00685            if ( Tcl_SplitList( ip, *argv, &num_cups, &cups ) == TCL_ERROR ) {
00686               *err_msg = "Cup data is not a list in event data";
00687               goto bail_event_data;
00688            }
00689 
00690            for ( i=0; i<num_cups; i++ ) {
00691                      CupData *cup_data;
00692 
00693                      cup_data = create_cup_data( ip, cups[i], err_msg );
00694                      if ( cup_data == NULL ) {
00695                          goto bail_event_data;
00696                      }
00697 
00698                      cupList.push_back(*cup_data);
00699            }
00700 
00701            Tcl_Free( (char*) cups );
00702            cups = NULL;
00703        } else {
00704            sprintf( err_buff, "Unrecognized argument `%s'", *argv );
00705            *err_msg = err_buff;
00706            goto bail_event_data;
00707        }
00708 
00709        NEXT_ARG;
00710     }
00711 
00712     /* Make sure mandatory fields have been specified */
00713     if ( event_data->name.empty() ) {
00714               *err_msg = "Must specify a name in event data";
00715               goto bail_event_data;
00716     }
00717 
00718     if ( event_data->icon.empty() ) {
00719               *err_msg = "Must specify an icon texture in event data";
00720               goto bail_event_data;
00721     }
00722 
00723     if ( cupList.empty() ) {
00724               *err_msg = "Must specify a cup list in event data";
00725               goto bail_event_data;
00726     }
00727 
00728     /* Create new event data object */
00729 
00730     event_data->cupList = cupList;
00731 
00732     bind_texture( event_data->name.c_str(), event_data->icon.c_str() );
00733 
00734     Tcl_Free( (char*) orig_argv );
00735     argv = NULL;
00736 
00737     return event_data;
00738 
00739 bail_event_data:
00740 
00741     if ( orig_argv ) {
00742        Tcl_Free( (char*) orig_argv );
00743     }
00744 
00745 /*    if ( name ) {
00746        free( name );
00747     }
00748 
00749     if ( icon ) {
00750        free( name );
00751     }
00752 */
00753     if ( cups ) {
00754        Tcl_Free( (char*) cups );
00755     }
00756 
00757     /* Clean out cup list */
00758 
00759     if ( event_data ) {
00760               delete( event_data );
00761     }
00762 
00763     return NULL;
00764 }
00765 
00766 
00767 /*---------------------------------------------------------------------------*/
00826 static int events_cb( ClientData cd, Tcl_Interp *ip,
00827                     int argc, CONST84 char **argv )
00828 {
00829     char *err_msg;
00830     CONST84 char **list = NULL;
00831     int num_events;
00832     int i;
00833     // Make sure module has been initialized
00834     check_assertion( initialized,
00835                    "course_mgr module not initialized" );
00836 
00837     if ( argc != 2 ) {
00838               err_msg = "Incorrect number of arguments";
00839               goto bail_events;
00840     }
00841 
00842     if ( Tcl_SplitList( ip, argv[1], &num_events, &list ) == TCL_ERROR ) {
00843               err_msg = "Argument is not a list";
00844               goto bail_events;
00845     }
00846 
00847     //if ( last_event != NULL ) {
00848        //err_msg = "tux_events has already been called; it can only be called "
00849        //    "once.";
00850        //goto bail_events;
00851     //}
00852 
00853     for (i=0; i<num_events; i++) {
00854               EventData *data = create_event_data( ip, list[i], &err_msg );
00855 
00856               if ( data == NULL ) {
00857                   goto bail_events;
00858               }
00859 
00860               eventList.push_back(*data);
00861     }
00862     Tcl_Free( (char*) list );
00863     list = NULL;
00864 
00865     return TCL_OK;
00866 
00867 bail_events:
00868     if ( list != NULL ) {
00869               Tcl_Free( (char*) list );
00870     }
00871 
00872     Tcl_AppendResult(
00873        ip,
00874        "Error in call to tux_events: ", 
00875        err_msg,
00876        "\n",
00877        "Usage: tux_events { list of event data }",
00878        (NULL) );
00879        return TCL_ERROR;
00880 }
00881 
00882 
00883 /*---------------------------------------------------------------------------*/
00890 static int get_race_conditions_cb( ClientData cd, Tcl_Interp *ip,
00891                                int argc, CONST84 char **argv )
00892 {
00893     char *err_msg;
00894     Tcl_Obj *result;
00895 
00896     if ( argc != 1 ) {
00897               err_msg = "Incorrect number of arguments";
00898               goto bail_race_conditions;
00899     }
00900 
00901        result = Tcl_NewStringObj(
00902        race_condition_names[ gameMgr->getCurrentRace().condition ],
00903        strlen( race_condition_names[ gameMgr->getCurrentRace().condition ] ) );
00904 
00905     Tcl_SetObjResult( ip, result );
00906 
00907     return TCL_OK;
00908 
00909 bail_race_conditions:
00910 
00911     Tcl_AppendResult(
00912        ip,
00913        "Error in call to tux_get_race_conditions: ", 
00914        err_msg,
00915        "\n",
00916        "Usage: tux_get_race_conditions",
00917        (NULL) );
00918     return TCL_ERROR;
00919 }
00920 
00921 void register_course_manager_callbacks( Tcl_Interp *ip )
00922 {
00923     Tcl_CreateCommand (ip, "tux_open_courses", open_courses_cb, 0,0);
00924     Tcl_CreateCommand (ip, "tux_events", events_cb, 0,0);
00925     Tcl_CreateCommand (ip, "tux_get_race_conditions", 
00926                      get_race_conditions_cb, 0,0);
00927 }
00928 
00929 
00930 
00931 /* EOF */