Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

be_aas_main.c

Go to the documentation of this file.
00001 /*
00002 ===========================================================================
00003 Copyright (C) 1999-2005 Id Software, Inc.
00004 
00005 This file is part of Quake III Arena source code.
00006 
00007 Quake III Arena source code is free software; you can redistribute it
00008 and/or modify it under the terms of the GNU General Public License as
00009 published by the Free Software Foundation; either version 2 of the License,
00010 or (at your option) any later version.
00011 
00012 Quake III Arena source code is distributed in the hope that it will be
00013 useful, 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 Foobar; if not, write to the Free Software
00019 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020 ===========================================================================
00021 */
00022 
00023 /*****************************************************************************
00024  * name:        be_aas_main.c
00025  *
00026  * desc:        AAS
00027  *
00028  * $Archive: /MissionPack/code/botlib/be_aas_main.c $
00029  *
00030  *****************************************************************************/
00031 
00032 #include "../game/q_shared.h"
00033 #include "l_memory.h"
00034 #include "l_libvar.h"
00035 #include "l_utils.h"
00036 #include "l_script.h"
00037 #include "l_precomp.h"
00038 #include "l_struct.h"
00039 #include "l_log.h"
00040 #include "aasfile.h"
00041 #include "../game/botlib.h"
00042 #include "../game/be_aas.h"
00043 #include "be_aas_funcs.h"
00044 #include "be_interface.h"
00045 #include "be_aas_def.h"
00046 
00047 aas_t aasworld;
00048 
00049 libvar_t *saveroutingcache;
00050 
00051 //===========================================================================
00052 //
00053 // Parameter:               -
00054 // Returns:                 -
00055 // Changes Globals:     -
00056 //===========================================================================
00057 void QDECL AAS_Error(char *fmt, ...)
00058 {
00059     char str[1024];
00060     va_list arglist;
00061 
00062     va_start(arglist, fmt);
00063     vsprintf(str, fmt, arglist);
00064     va_end(arglist);
00065     botimport.Print(PRT_FATAL, str);
00066 } //end of the function AAS_Error
00067 //===========================================================================
00068 //
00069 // Parameter:               -
00070 // Returns:                 -
00071 // Changes Globals:     -
00072 //===========================================================================
00073 char *AAS_StringFromIndex(char *indexname, char *stringindex[], int numindexes, int index)
00074 {
00075     if (!aasworld.indexessetup)
00076     {
00077         botimport.Print(PRT_ERROR, "%s: index %d not setup\n", indexname, index);
00078         return "";
00079     } //end if
00080     if (index < 0 || index >= numindexes)
00081     {
00082         botimport.Print(PRT_ERROR, "%s: index %d out of range\n", indexname, index);
00083         return "";
00084     } //end if
00085     if (!stringindex[index])
00086     {
00087         if (index)
00088         {
00089             botimport.Print(PRT_ERROR, "%s: reference to unused index %d\n", indexname, index);
00090         } //end if
00091         return "";
00092     } //end if
00093     return stringindex[index];
00094 } //end of the function AAS_StringFromIndex
00095 //===========================================================================
00096 //
00097 // Parameter:               -
00098 // Returns:                 -
00099 // Changes Globals:     -
00100 //===========================================================================
00101 int AAS_IndexFromString(char *indexname, char *stringindex[], int numindexes, char *string)
00102 {
00103     int i;
00104     if (!aasworld.indexessetup)
00105     {
00106         botimport.Print(PRT_ERROR, "%s: index not setup \"%s\"\n", indexname, string);
00107         return 0;
00108     } //end if
00109     for (i = 0; i < numindexes; i++)
00110     {
00111         if (!stringindex[i]) continue;
00112         if (!Q_stricmp(stringindex[i], string)) return i;
00113     } //end for
00114     return 0;
00115 } //end of the function AAS_IndexFromString
00116 //===========================================================================
00117 //
00118 // Parameter:               -
00119 // Returns:                 -
00120 // Changes Globals:     -
00121 //===========================================================================
00122 char *AAS_ModelFromIndex(int index)
00123 {
00124     return AAS_StringFromIndex("ModelFromIndex", &aasworld.configstrings[CS_MODELS], MAX_MODELS, index);
00125 } //end of the function AAS_ModelFromIndex
00126 //===========================================================================
00127 //
00128 // Parameter:               -
00129 // Returns:                 -
00130 // Changes Globals:     -
00131 //===========================================================================
00132 int AAS_IndexFromModel(char *modelname)
00133 {
00134     return AAS_IndexFromString("IndexFromModel", &aasworld.configstrings[CS_MODELS], MAX_MODELS, modelname);
00135 } //end of the function AAS_IndexFromModel
00136 //===========================================================================
00137 //
00138 // Parameter:               -
00139 // Returns:                 -
00140 // Changes Globals:     -
00141 //===========================================================================
00142 void AAS_UpdateStringIndexes(int numconfigstrings, char *configstrings[])
00143 {
00144     int i;
00145     //set string pointers and copy the strings
00146     for (i = 0; i < numconfigstrings; i++)
00147     {
00148         if (configstrings[i])
00149         {
00150             //if (aasworld.configstrings[i]) FreeMemory(aasworld.configstrings[i]);
00151             aasworld.configstrings[i] = (char *) GetMemory(strlen(configstrings[i]) + 1);
00152             strcpy(aasworld.configstrings[i], configstrings[i]);
00153         } //end if
00154     } //end for
00155     aasworld.indexessetup = qtrue;
00156 } //end of the function AAS_UpdateStringIndexes
00157 //===========================================================================
00158 //
00159 // Parameter:               -
00160 // Returns:                 -
00161 // Changes Globals:     -
00162 //===========================================================================
00163 int AAS_Loaded(void)
00164 {
00165     return aasworld.loaded;
00166 } //end of the function AAS_Loaded
00167 //===========================================================================
00168 //
00169 // Parameter:               -
00170 // Returns:                 -
00171 // Changes Globals:     -
00172 //===========================================================================
00173 int AAS_Initialized(void)
00174 {
00175     return aasworld.initialized;
00176 } //end of the function AAS_Initialized
00177 //===========================================================================
00178 //
00179 // Parameter:               -
00180 // Returns:                 -
00181 // Changes Globals:     -
00182 //===========================================================================
00183 void AAS_SetInitialized(void)
00184 {
00185     aasworld.initialized = qtrue;
00186     botimport.Print(PRT_MESSAGE, "AAS initialized.\n");
00187 #ifdef DEBUG
00188     //create all the routing cache
00189     //AAS_CreateAllRoutingCache();
00190     //
00191     //AAS_RoutingInfo();
00192 #endif
00193 } //end of the function AAS_SetInitialized
00194 //===========================================================================
00195 //
00196 // Parameter:               -
00197 // Returns:                 -
00198 // Changes Globals:     -
00199 //===========================================================================
00200 void AAS_ContinueInit(float time)
00201 {
00202     //if no AAS file loaded
00203     if (!aasworld.loaded) return;
00204     //if AAS is already initialized
00205     if (aasworld.initialized) return;
00206     //calculate reachability, if not finished return
00207     if (AAS_ContinueInitReachability(time)) return;
00208     //initialize clustering for the new map
00209     AAS_InitClustering();
00210     //if reachability has been calculated and an AAS file should be written
00211     //or there is a forced data optimization
00212     if (aasworld.savefile || ((int)LibVarGetValue("forcewrite")))
00213     {
00214         //optimize the AAS data
00215         if ((int)LibVarValue("aasoptimize", "0")) AAS_Optimize();
00216         //save the AAS file
00217         if (AAS_WriteAASFile(aasworld.filename))
00218         {
00219             botimport.Print(PRT_MESSAGE, "%s written succesfully\n", aasworld.filename);
00220         } //end if
00221         else
00222         {
00223             botimport.Print(PRT_ERROR, "couldn't write %s\n", aasworld.filename);
00224         } //end else
00225     } //end if
00226     //initialize the routing
00227     AAS_InitRouting();
00228     //at this point AAS is initialized
00229     AAS_SetInitialized();
00230 } //end of the function AAS_ContinueInit
00231 //===========================================================================
00232 // called at the start of every frame
00233 //
00234 // Parameter:               -
00235 // Returns:                 -
00236 // Changes Globals:     -
00237 //===========================================================================
00238 int AAS_StartFrame(float time)
00239 {
00240     aasworld.time = time;
00241     //unlink all entities that were not updated last frame
00242     AAS_UnlinkInvalidEntities();
00243     //invalidate the entities
00244     AAS_InvalidateEntities();
00245     //initialize AAS
00246     AAS_ContinueInit(time);
00247     //
00248     aasworld.frameroutingupdates = 0;
00249     //
00250     if (bot_developer)
00251     {
00252         if (LibVarGetValue("showcacheupdates"))
00253         {
00254             AAS_RoutingInfo();
00255             LibVarSet("showcacheupdates", "0");
00256         } //end if
00257         if (LibVarGetValue("showmemoryusage"))
00258         {
00259             PrintUsedMemorySize();
00260             LibVarSet("showmemoryusage", "0");
00261         } //end if
00262         if (LibVarGetValue("memorydump"))
00263         {
00264             PrintMemoryLabels();
00265             LibVarSet("memorydump", "0");
00266         } //end if
00267     } //end if
00268     //
00269     if (saveroutingcache->value)
00270     {
00271         AAS_WriteRouteCache();
00272         LibVarSet("saveroutingcache", "0");
00273     } //end if
00274     //
00275     aasworld.numframes++;
00276     return BLERR_NOERROR;
00277 } //end of the function AAS_StartFrame
00278 //===========================================================================
00279 //
00280 // Parameter:               -
00281 // Returns:                 -
00282 // Changes Globals:     -
00283 //===========================================================================
00284 float AAS_Time(void)
00285 {
00286     return aasworld.time;
00287 } //end of the function AAS_Time
00288 //===========================================================================
00289 //
00290 // Parameter:           -
00291 // Returns:             -
00292 // Changes Globals:     -
00293 //===========================================================================
00294 void AAS_ProjectPointOntoVector( vec3_t point, vec3_t vStart, vec3_t vEnd, vec3_t vProj )
00295 {
00296     vec3_t pVec, vec;
00297 
00298     VectorSubtract( point, vStart, pVec );
00299     VectorSubtract( vEnd, vStart, vec );
00300     VectorNormalize( vec );
00301     // project onto the directional vector for this segment
00302     VectorMA( vStart, DotProduct( pVec, vec ), vec, vProj );
00303 } //end of the function AAS_ProjectPointOntoVector
00304 //===========================================================================
00305 //
00306 // Parameter:               -
00307 // Returns:                 -
00308 // Changes Globals:     -
00309 //===========================================================================
00310 int AAS_LoadFiles(const char *mapname)
00311 {
00312     int errnum;
00313     char aasfile[MAX_PATH];
00314 //  char bspfile[MAX_PATH];
00315 
00316     strcpy(aasworld.mapname, mapname);
00317     //NOTE: first reset the entity links into the AAS areas and BSP leaves
00318     // the AAS link heap and BSP link heap are reset after respectively the
00319     // AAS file and BSP file are loaded
00320     AAS_ResetEntityLinks();
00321     // load bsp info
00322     AAS_LoadBSPFile();
00323 
00324     //load the aas file
00325     Com_sprintf(aasfile, MAX_PATH, "maps/%s.aas", mapname);
00326     errnum = AAS_LoadAASFile(aasfile);
00327     if (errnum != BLERR_NOERROR)
00328         return errnum;
00329 
00330     botimport.Print(PRT_MESSAGE, "loaded %s\n", aasfile);
00331     strncpy(aasworld.filename, aasfile, MAX_PATH);
00332     return BLERR_NOERROR;
00333 } //end of the function AAS_LoadFiles
00334 //===========================================================================
00335 // called everytime a map changes
00336 //
00337 // Parameter:               -
00338 // Returns:                 -
00339 // Changes Globals:     -
00340 //===========================================================================
00341 int AAS_LoadMap(const char *mapname)
00342 {
00343     int errnum;
00344 
00345     //if no mapname is provided then the string indexes are updated
00346     if (!mapname)
00347     {
00348         return 0;
00349     } //end if
00350     //
00351     aasworld.initialized = qfalse;
00352     //NOTE: free the routing caches before loading a new map because
00353     // to free the caches the old number of areas, number of clusters
00354     // and number of areas in a clusters must be available
00355     AAS_FreeRoutingCaches();
00356     //load the map
00357     errnum = AAS_LoadFiles(mapname);
00358     if (errnum != BLERR_NOERROR)
00359     {
00360         aasworld.loaded = qfalse;
00361         return errnum;
00362     } //end if
00363     //
00364     AAS_InitSettings();
00365     //initialize the AAS link heap for the new map
00366     AAS_InitAASLinkHeap();
00367     //initialize the AAS linked entities for the new map
00368     AAS_InitAASLinkedEntities();
00369     //initialize reachability for the new map
00370     AAS_InitReachability();
00371     //initialize the alternative routing
00372     AAS_InitAlternativeRouting();
00373     //everything went ok
00374     return 0;
00375 } //end of the function AAS_LoadMap
00376 //===========================================================================
00377 // called when the library is first loaded
00378 //
00379 // Parameter:               -
00380 // Returns:                 -
00381 // Changes Globals:     -
00382 //===========================================================================
00383 int AAS_Setup(void)
00384 {
00385     aasworld.maxclients = (int) LibVarValue("maxclients", "128");
00386     aasworld.maxentities = (int) LibVarValue("maxentities", "1024");
00387     // as soon as it's set to 1 the routing cache will be saved
00388     saveroutingcache = LibVar("saveroutingcache", "0");
00389     //allocate memory for the entities
00390     if (aasworld.entities) FreeMemory(aasworld.entities);
00391     aasworld.entities = (aas_entity_t *) GetClearedHunkMemory(aasworld.maxentities * sizeof(aas_entity_t));
00392     //invalidate all the entities
00393     AAS_InvalidateEntities();
00394     //force some recalculations
00395     //LibVarSet("forceclustering", "1");            //force clustering calculation
00396     //LibVarSet("forcereachability", "1");      //force reachability calculation
00397     aasworld.numframes = 0;
00398     return BLERR_NOERROR;
00399 } //end of the function AAS_Setup
00400 //===========================================================================
00401 //
00402 // Parameter:               -
00403 // Returns:                 -
00404 // Changes Globals:     -
00405 //===========================================================================
00406 void AAS_Shutdown(void)
00407 {
00408     AAS_ShutdownAlternativeRouting();
00409     //
00410     AAS_DumpBSPData();
00411     //free routing caches
00412     AAS_FreeRoutingCaches();
00413     //free aas link heap
00414     AAS_FreeAASLinkHeap();
00415     //free aas linked entities
00416     AAS_FreeAASLinkedEntities();
00417     //free the aas data
00418     AAS_DumpAASData();
00419     //free the entities
00420     if (aasworld.entities) FreeMemory(aasworld.entities);
00421     //clear the aasworld structure
00422     Com_Memset(&aasworld, 0, sizeof(aas_t));
00423     //aas has not been initialized
00424     aasworld.initialized = qfalse;
00425     //NOTE: as soon as a new .bsp file is loaded the .bsp file memory is
00426     // freed an reallocated, so there's no need to free that memory here
00427     //print shutdown
00428     botimport.Print(PRT_MESSAGE, "AAS shutdown.\n");
00429 } //end of the function AAS_Shutdown

Generated on Thu Aug 25 12:37:09 2005 for Quake III Arena by  doxygen 1.3.9.1