Main Page | Alphabetical List | Compound List | File List | Compound Members | File Members

Entities.c

Go to the documentation of this file.
00001 /****************************************************************************************/
00002 /*  Entities.c                                                                          */
00003 /*                                                                                      */
00004 /*  Author: Eli Boling / John Pollard                                                   */
00005 /*  Description: EntitySet creation / Entity Compiler                                   */
00006 /*                                                                                      */
00007 /*  The contents of this file are subject to the Genesis3D Public License               */
00008 /*  Version 1.01 (the "License"); you may not use this file except in                   */
00009 /*  compliance with the License. You may obtain a copy of the License at                */
00010 /*  http://www.genesis3d.com                                                            */
00011 /*                                                                                      */
00012 /*  Software distributed under the License is distributed on an "AS IS"                 */
00013 /*  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See                */
00014 /*  the License for the specific language governing rights and limitations              */
00015 /*  under the License.                                                                  */
00016 /*                                                                                      */
00017 /*  The Original Code is Genesis3D, released March 25, 1999.                            */
00018 /*Genesis3D Version 1.1 released November 15, 1999                            */
00019 /*  Copyright (C) 1999 WildTangent, Inc. All Rights Reserved           */
00020 /*                                                                                      */
00021 /****************************************************************************************/
00022 #include <Windows.h>
00023 #include <Assert.h>
00024 
00025 #include "Entities.h"
00026 #include "BaseType.h"
00027 #include "Errorlog.h"
00028 #include "Vec3d.h"
00029 #include "Ram.h"
00030 
00031 // These are temporary until we find a better way to get models pointers into the entity stuff
00032 #include "World.h"
00033 #include "GBSPFile.h"
00034 
00035 
00036 //=====================================================================================
00037 //      Local Static Globals
00038 //=====================================================================================
00039 
00040 //=====================================================================================
00041 //      Local Static Function prototypes
00042 //=====================================================================================
00043 static          geWorld *GWorld;                // Temp global world for testing new entity stuff
00044 
00045 //====================================================================================
00046 //====================================================================================
00047 static geBoolean InsertEntityInClassList(geWorld *World, geEntity *Entity)
00048 {
00049         const char                      *EntClassName;
00050         geWorld_EntClassSet     *WSet;
00051         int32                           i;
00052 
00053         if (!Entity->Class)             // Ignore all no classes
00054                 return GE_TRUE;
00055         
00056         assert(Entity->Class->Name);    // Must have a class name
00057         
00058         EntClassName = Entity->Class->Name;
00059 
00060         WSet = World->EntClassSets;
00061 
00062         for (i=0; i< World->NumEntClassSets; i++)
00063         {
00064                 if (!WSet[i].ClassName)
00065                         continue;
00066 
00067                 if (!stricmp(WSet[i].ClassName, EntClassName))
00068                 {
00069                         // Add entity to this class set...
00070                         if (!geEntity_EntitySetAddEntity(WSet[i].Set, Entity))
00071                                 return GE_FALSE;
00072 
00073                         return GE_TRUE;
00074                 }
00075         }
00076 
00077         if (i >= MAX_WORLD_ENT_CLASS_SETS)
00078                 return GE_FALSE;                                        // oh well...
00079 
00080         // Create a new entity set
00081         WSet[i].Set = geEntity_EntitySetCreate();
00082 
00083         // Insert the entity into a new class set
00084         WSet[i].ClassName = EntClassName;
00085         geEntity_EntitySetAddEntity(WSet[i].Set, Entity);
00086 
00087         World->NumEntClassSets++;
00088 
00089         return GE_TRUE;
00090 }
00091 
00092 //====================================================================================
00093 //      Ent_WorldInit
00094 //      Lets this module initialize data that it owns in the world
00095 //====================================================================================
00096 geBoolean Ent_WorldInit(geWorld *World)
00097 {
00098         GBSP_BSPData            *BSP;
00099         geEntity_EntitySet      *EntitySet;
00100         geEntity                        *Entity;
00101 
00102         assert(World != NULL);
00103         
00104         GWorld = World;
00105 
00106         World->NumEntClassSets = 0;
00107 
00108         if ( ! World->CurrentBSP )
00109                 return GE_TRUE;
00110 
00111         BSP = &(World->CurrentBSP->BSPData);
00112 
00113         if (BSP->NumGFXEntData == 0)
00114                 return GE_TRUE;                         // Nothing to do...
00115 
00116         EntitySet = LoadEntitySet(BSP->GFXEntData, BSP->NumGFXEntData);
00117 
00118         if (!EntitySet)
00119                 return GE_FALSE;
00120 
00121         // Insert default set...
00122         World->EntClassSets[0].ClassName = NULL;
00123         World->EntClassSets[0].Set = EntitySet;
00124         World->NumEntClassSets++;
00125                 
00126         // Build class sets
00127         Entity = NULL;
00128         while (1)
00129         {
00130                 Entity = geEntity_EntitySetGetNextEntity(EntitySet, Entity);
00131 
00132                 if (!Entity)
00133                         break;          // Done
00134 
00135                 InsertEntityInClassList(World, Entity);
00136         }
00137 
00138         return GE_TRUE;
00139 }
00140 
00141 //====================================================================================
00142 //      Ent_WorldShutdown
00143 //      Lets this module shutdown data that it owns in the world
00144 //====================================================================================
00145 void Ent_WorldShutdown(geWorld *World)
00146 {
00147         int32           i;
00148 
00149         assert(World);
00150         
00151         for (i=0; i< World->NumEntClassSets; i++)
00152                 geEntity_EntitySetDestroy(World->EntClassSets[i].Set);
00153 }
00154 
00155 //====================================================================================
00156 //      CopyString
00157 //====================================================================================
00158 static char *CopyString(const char *String)
00159 {
00160         char    *NewString;
00161 
00162         NewString = geRam_Allocate(strlen(String)+1);
00163 
00164         if (!NewString)
00165                 return NULL;
00166 
00167         strcpy(NewString, String);
00168 
00169         return NewString;
00170 }
00171 
00172 //====================================================================================
00173 //      geEntity_Create
00174 //====================================================================================
00175 geEntity *geEntity_Create(void)
00176 {
00177         geEntity        *Entity;
00178 
00179         Entity = geRam_Allocate(sizeof(geEntity));
00180 
00181         if (!Entity)
00182                 return NULL;
00183 
00184         memset(Entity, 0, sizeof(geEntity));
00185 
00186         return Entity;
00187 }
00188 
00189 //====================================================================================
00190 //      geEntity_Destroy
00191 //      NOTE - This currently does garbage collection on the epairs that were inserted in the entity
00192 //====================================================================================
00193 void geEntity_Destroy(geEntity *Entity)
00194 {
00195         geEntity_Epair  *Epair, *Next;
00196 
00197         assert(Entity);
00198 
00199         for (Epair = Entity->Epairs; Epair; Epair = Next)
00200         {
00201                 Next = Epair->Next;
00202 
00203                 geEntity_EpairDestroy(Epair);
00204         }
00205 
00206         if (Entity->UserData)
00207                 geRam_Free(Entity->UserData);
00208 
00209         geRam_Free(Entity);
00210 }
00211 
00212 //====================================================================================
00213 //      geEntity_GetUserData
00214 //====================================================================================
00215 GENESISAPI void *geEntity_GetUserData(geEntity *Entity)
00216 {
00217         assert(Entity);
00218 
00219         return Entity->UserData;
00220 }
00221 
00222 //====================================================================================
00223 //      geEntity_GetModelNumForKey
00224 //====================================================================================
00225 geBoolean geEntity_GetModelNumForKey(geEntity *Entity, const char *Key, int32 *ModelNum)
00226 {
00227         geEntity_Epair  *Epair;
00228         int32                   Value;
00229 
00230         for (Epair = Entity->Epairs; Epair; Epair = Epair->Next)
00231         {
00232                 if (!stricmp(Epair->Key, Key))
00233                 {
00234                         if (Epair->Value[0] == '*')
00235                                 sscanf(Epair->Value+1, "%d", &Value);
00236                         else
00237                                 sscanf(Epair->Value, "%d", &Value);
00238 
00239                         *ModelNum = (int32)Value;
00240                         return GE_TRUE;
00241                 }
00242         }
00243         return GE_FALSE;                                // not found !
00244 
00245 }
00246 
00247 //====================================================================================
00248 //      geEntity_AddEpair
00249 //====================================================================================
00250 geBoolean geEntity_AddEpair(geEntity *Entity, geEntity_Epair *Epair)
00251 {
00252         geEntity_Epair  *Ep;
00253 
00254         assert(Entity);
00255         assert(Epair);
00256 
00257         assert(Epair->Next == NULL);            // Make sure this is a fresh one (ahh yahh)
00258         
00259         if (!Entity->Epairs)
00260         {
00261                 Entity->Epairs = Epair;
00262                 return GE_TRUE;
00263         }
00264 
00265         // Jump to end of list 
00266         for (Ep = Entity->Epairs; Ep->Next; Ep = Ep->Next);     
00267 
00268         Ep->Next = Epair;
00269 
00270         return GE_TRUE;
00271 }
00272 
00273 //====================================================================================
00274 //      geEntity_GetStringForKey
00275 //====================================================================================
00276 const char *geEntity_GetStringForKey(const geEntity *Entity, const char *Key)
00277 {
00278         geEntity_Epair  *Epair;
00279 
00280         for (Epair = Entity->Epairs; Epair; Epair = Epair->Next)
00281         {
00282                 if (!stricmp(Epair->Key, Key))
00283                 {
00284                         return Epair->Value;
00285                 }
00286         }
00287         return NULL;                            // not found!
00288 }
00289 
00290 //====================================================================================
00291 //      geEntity_EpairCreate
00292 //====================================================================================
00293 geEntity_Epair *geEntity_EpairCreate(void)
00294 {
00295         geEntity_Epair  *Epair;
00296 
00297         Epair = geRam_Allocate(sizeof(geEntity_Epair));
00298 
00299         if (!Epair)
00300                 return NULL;
00301 
00302         memset(Epair, 0, sizeof(geEntity_Epair));
00303 
00304         return Epair;
00305 }
00306 
00307 //====================================================================================
00308 //      geEntity_EpairDestroy
00309 //====================================================================================
00310 void geEntity_EpairDestroy(geEntity_Epair *Epair)
00311 {
00312         assert(Epair);
00313 
00314         if (Epair->Key)
00315                 geRam_Free(Epair->Key);
00316 
00317         if (Epair->Value)
00318                 geRam_Free(Epair->Value);
00319 
00320         geRam_Free(Epair);
00321 }
00322 
00323 //====================================================================================
00324 //      geEntity_FieldCreate
00325 //====================================================================================
00326 geEntity_Field *geEntity_FieldCreate(const char *Name, int32 Offset, geEntity_Class *TypeClass)
00327 {
00328         geEntity_Field  *Field;
00329 
00330         Field = GE_RAM_ALLOCATE_STRUCT(geEntity_Field);
00331 
00332         if (!Field)
00333                 return NULL;
00334 
00335         memset(Field, 0, sizeof(geEntity_Field));
00336 
00337         if (Name)
00338                 Field->Name = CopyString(Name);
00339 
00340         Field->Offset = Offset;
00341         Field->TypeClass = TypeClass;
00342 
00343         return Field;
00344 }
00345 
00346 //====================================================================================
00347 //      geEntity_FieldDestroy
00348 //====================================================================================
00349 void geEntity_FieldDestroy(geEntity_Field *Field)
00350 {
00351         assert(Field);
00352 
00353         if (Field->Name)
00354                 geRam_Free(Field->Name);
00355 
00356         geRam_Free(Field);
00357 }
00358 
00359 //====================================================================================
00360 //      geEntity_ClassCreate
00361 //====================================================================================
00362 geEntity_Class *geEntity_ClassCreate(geEntity_ClassType Type, const char *Name, int32 TypeSize)
00363 {
00364         geEntity_Class  *Class;
00365 
00366         Class = GE_RAM_ALLOCATE_STRUCT(geEntity_Class);
00367 
00368         if (!Class)
00369                 return NULL;
00370 
00371         memset(Class, 0, sizeof(geEntity_Class));
00372 
00373         Class->Type = Type;
00374 
00375         if (Name)
00376                 Class->Name = CopyString(Name);
00377 
00378         Class->TypeSize = TypeSize;
00379 
00380         return Class;
00381 }
00382 
00383 //====================================================================================
00384 //      geEntity_ClassDestroy
00385 //====================================================================================
00386 void geEntity_ClassDestroy(geEntity_Class *Class)
00387 {
00388         geEntity_Field  *Field, *NextField;
00389         assert(Class);
00390 
00391         for (Field = Class->Fields; Field; Field = NextField )
00392         {
00393                 NextField = Field->Next;
00394                 geEntity_FieldDestroy(Field);
00395         }
00396         if (Class->Name)
00397                 geRam_Free(Class->Name);
00398 
00399         geRam_Free(Class);
00400 }
00401 
00402 //====================================================================================
00403 //      geEntity_ClassAddField
00404 //====================================================================================
00405 geBoolean geEntity_ClassAddField(geEntity_Class *Class, geEntity_Field *Field)
00406 {
00407         assert(Class);
00408         assert(Field);
00409 
00410         // Put at the beggining
00411         Field->Next = Class->Fields;
00412         Class->Fields = Field;
00413 
00414         // Grow fieldsize by Fields TypeClass size
00415         Class->FieldSize += Field->TypeClass->TypeSize;
00416 
00417         return GE_TRUE;
00418 }
00419 
00420 //====================================================================================
00421 //      geEntity_ClassFindFieldByName
00422 //====================================================================================
00423 geEntity_Field *geEntity_ClassFindFieldByName(geEntity_Class *Class, const char *Name)
00424 {
00425         geEntity_Field  *Field;
00426 
00427         assert(Class);
00428 
00429         for (Field = Class->Fields; Field; Field = Field->Next)
00430         {
00431                 if      (!stricmp(Field->Name, Name))
00432                         return Field;
00433                 
00434         }
00435 
00436         return NULL;
00437 }
00438 
00439 //====================================================================================
00440 //      geEntity_EntitySetCreate
00441 //====================================================================================
00442 geEntity_EntitySet *geEntity_EntitySetCreate(void)
00443 {
00444         geEntity_EntitySet              *EntitySet;
00445 
00446         EntitySet = geRam_Allocate(sizeof(geEntity_EntitySet));
00447 
00448         if (!EntitySet)
00449                 return NULL;
00450 
00451         memset(EntitySet, 0, sizeof(geEntity_EntitySet));
00452 
00453         return EntitySet;
00454 }
00455 
00456 //====================================================================================
00457 //      geEntity_EntitySetDestroy
00458 //      NOTE - This does garbage collection to anything added the the set
00459 //====================================================================================
00460 void geEntity_EntitySetDestroy(geEntity_EntitySet *EntitySet)
00461 {
00462         geEntity_EntitySet      *Set, *Next;
00463         geEntity_Class          *Class, *NextClass;
00464         
00465         assert(EntitySet);
00466 
00467         if (EntitySet->OwnsEntities)            // Free stuff if we created all this stuff
00468         {
00469                 for (Class = EntitySet->Classes; Class; Class = NextClass)
00470                 {                          
00471                         NextClass = Class->Next;
00472 
00473                         geEntity_ClassDestroy(Class);
00474                 }
00475 
00476                 for (Set = EntitySet; Set; Set = Next)
00477                 {
00478                         Next = Set->Next;
00479                         if      (Set->Entity)
00480                                 geEntity_Destroy(Set->Entity);
00481                 }
00482         }
00483 
00484         // Finclaly destroy the sets themselves...
00485         for (Set = EntitySet; Set; Set = Next)
00486         {
00487                 Next = Set->Next;
00488 
00489                 geRam_Free(Set);
00490         }
00491 }
00492 
00493 //====================================================================================
00494 //      geEntity_EntitySetFindClassByName
00495 //====================================================================================
00496 geEntity_Class *geEntity_EntitySetFindClassByName(geEntity_EntitySet *Set, const char *Name)
00497 {
00498         geEntity_Class  *Class;
00499 
00500         assert(Set);
00501 
00502         for (Class = Set->Classes; Class; Class = Class->Next)
00503         {
00504                 if      (!stricmp(Class->Name, Name))
00505                         return Class;
00506         }
00507 
00508         return NULL;    // Not found!!!
00509 }
00510 
00511 GENESISAPI void geEntity_GetName(const geEntity *Entity, char *Buff, int MaxLen)
00512 {
00513         const char *    EntName;
00514         int                             Length;
00515 
00516         assert(Entity);
00517         assert(Buff);
00518         
00519         EntName = geEntity_GetStringForKey(Entity, "%Name%");
00520         assert(EntName);
00521         Length = strlen(EntName) + 1;
00522         memcpy(Buff, EntName, min(Length, MaxLen));
00523 }
00524 
00525 //====================================================================================
00526 //      geEntity_EntitySetFindEntityByName
00527 //====================================================================================
00528 geEntity *geEntity_EntitySetFindEntityByName(geEntity_EntitySet *EntitySet, const char *Name)
00529 {
00530         const char                      *EntName;
00531         geEntity_EntitySet      *Set;
00532 
00533         assert(EntitySet);
00534         assert(Name);
00535 
00536         for (Set = EntitySet; Set; Set = Set->Next)
00537         {
00538                 EntName = geEntity_GetStringForKey(Set->Entity, "%Name%");
00539 
00540                 if (!EntName)
00541                         continue;
00542 
00543                 if (!stricmp(Name, EntName))
00544                         return Set->Entity;
00545         }
00546         
00547         return NULL;
00548 }
00549 
00550 //====================================================================================
00551 //      geEntity_EntitySetAddEntity
00552 //====================================================================================
00553 geBoolean geEntity_EntitySetAddEntity(geEntity_EntitySet *EntitySet, geEntity *Entity)
00554 {
00555         geEntity_EntitySet      *NewSet, *Set;
00556         
00557         assert(EntitySet);
00558         assert(Entity);
00559 
00560         // If no entities in list, just make this one the first
00561         if (!EntitySet->Entity)
00562         {
00563                 assert(EntitySet->Next == NULL);
00564                 assert(EntitySet->Current == NULL);
00565 
00566                 EntitySet->Entity = Entity;
00567                 return GE_TRUE;
00568         }
00569 
00570         NewSet = geEntity_EntitySetCreate();
00571 
00572         if (!NewSet)
00573                 return GE_FALSE;
00574 
00575         // Store the entity
00576         NewSet->Entity = Entity;
00577         
00578         // Jump to end of list (we allways want them to work on the first set in the list...)
00579         for (Set = EntitySet; Set->Next; Set = Set->Next);              
00580 
00581         // Add the newset
00582         Set->Next = NewSet;
00583 return GE_TRUE;
00584 }
00585 
00586 //====================================================================================
00587 //      geEntity_EntitySetGetNextEntity
00588 //====================================================================================
00589 GENESISAPI geEntity *geEntity_EntitySetGetNextEntity(geEntity_EntitySet *EntitySet, geEntity *Entity)
00590 {
00591         geEntity_EntitySet              *Set, *NextSet;
00592 
00593         assert(EntitySet);
00594 
00595         if (!Entity)
00596         {
00597                 EntitySet->Current = EntitySet;
00598                 return EntitySet->Entity;
00599         }
00600 
00601         assert(EntitySet->Current);
00602 
00603         // Search is easy if this was the last entity we returned
00604         if (EntitySet->Current->Entity == Entity)
00605         {
00606                 NextSet = EntitySet->Current->Next;
00607 
00608                 if (!NextSet)
00609                         return NULL;            // No more in the list
00610 
00611                 EntitySet->Current = NextSet;
00612                 return NextSet->Entity;
00613         }
00614 
00615         // Must do a search now, that'll teach'em to jump around...
00616         for (Set = EntitySet; Set; Set = Set->Next)
00617         {
00618                 assert(Set->Entity);
00619 
00620                 if (Set->Entity == Entity)
00621                 {
00622                         NextSet = Set->Next;
00623 
00624                         EntitySet->Current = NextSet;
00625                         return NextSet->Entity;
00626                 }
00627         }
00628 
00629         return NULL;
00630 }
00631 
00632 //====================================================================================
00633 //      geEntity_EntitySetAddClass
00634 //====================================================================================
00635 geBoolean geEntity_EntitySetAddClass(geEntity_EntitySet *EntitySet, geEntity_Class *Class)
00636 {
00637         assert(EntitySet);
00638         assert(Class);
00639 
00640         assert(Class->Next == NULL);            // We want fresh ones only
00641 
00642         // Just put in front of list
00643         Class->Next = EntitySet->Classes;
00644         EntitySet->Classes = Class;
00645 
00646         return GE_TRUE;
00647 }
00648 
00649 //====================================================================================
00650 //      BuildClassTypes
00651 //====================================================================================
00652 static geBoolean BuildClassTypes(geEntity_EntitySet *EntitySet)
00653 {
00654         const char                      *Name;
00655         geEntity_Class          *Class;
00656         geEntity_EntitySet      *Set;
00657         
00658         // Fill in the pre-defined atomic types
00659         Class = geEntity_ClassCreate(TYPE_INT, "int", sizeof(int32));
00660         geEntity_EntitySetAddClass(EntitySet, Class);
00661 //
00662 // For Reality Factory floating point data type in entities
00663 // is set to be geFloat, not float as in Gedit
00664 //
00665         Class = geEntity_ClassCreate(TYPE_FLOAT, "geFloat", sizeof(geFloat));
00666         geEntity_EntitySetAddClass(EntitySet, Class);
00667 
00668         Class = geEntity_ClassCreate(TYPE_COLOR, "color", sizeof(GE_RGBA));
00669         geEntity_EntitySetAddClass(EntitySet, Class);
00670 
00671         Class = geEntity_ClassCreate(TYPE_POINT, "point", sizeof(geVec3d));
00672         geEntity_EntitySetAddClass(EntitySet, Class);
00673 
00674         Class = geEntity_ClassCreate(TYPE_STRING, "string", sizeof(char *));
00675         geEntity_EntitySetAddClass(EntitySet, Class);
00676 
00677         Class = geEntity_ClassCreate(TYPE_PTR, "ptr", sizeof(void *));
00678         geEntity_EntitySetAddClass(EntitySet, Class);
00679 
00680         Class = geEntity_ClassCreate(TYPE_MODEL, "model", sizeof(void*));
00681         geEntity_EntitySetAddClass(EntitySet, Class);
00682         
00683         //      Find all the %typedef% keywords, and allocate them as TYPE_STRUCT's
00684         for (Set = EntitySet; Set; Set = Set->Next)
00685         {
00686                 geEntity *Entity;
00687                 
00688                 Entity = Set->Entity;
00689 
00690                 Name = geEntity_GetStringForKey(Entity, "classname");
00691 
00692                 if (!Name)
00693                         continue;       
00694 
00695                 if (stricmp(Name, "%typedef%")) // No %typedef% info
00696                         continue;
00697 
00698                 Name = geEntity_GetStringForKey(Entity, "%typename%");
00699 
00700                 if (!Name)
00701                         return GE_FALSE;
00702 
00703                 Class = geEntity_ClassCreate(TYPE_STRUCT, Name, sizeof(void*));
00704 
00705                 if (!Class)
00706                         goto ExitWithError;
00707 
00708                 if (!geEntity_EntitySetAddClass(EntitySet, Class))
00709                         goto ExitWithError;
00710         }
00711 
00712         for (Set = EntitySet; Set; Set = Set->Next)
00713         {
00714                 geEntity                *Entity;
00715                 geEntity_Epair  *Epair;
00716 
00717                 Entity = Set->Entity;
00718 
00719                 Name = geEntity_GetStringForKey(Entity, "classname");
00720 
00721                 if (!Name)              // Not a class entity (Error?)
00722                         continue;       
00723 
00724                 if (stricmp(Name, "%typedef%")) // Not a typedef
00725                         continue;
00726                 
00727                 Name = geEntity_GetStringForKey(Entity, "%typename%");
00728 
00729                 if (!Name)
00730                         return GE_FALSE;
00731 
00732                 Class = geEntity_EntitySetFindClassByName(EntitySet, Name);
00733 
00734                 if (!Class)
00735                         continue;       // Oops, this %typedef% will have no fields
00736 
00737                 for (Epair = Entity->Epairs; Epair; Epair = Epair->Next)
00738                 {
00739                         geEntity_Class  *TypeClass;
00740                         geEntity_Field  *Field;
00741 
00742                         // Skip classname and %typename%
00743                         if      (!stricmp(Epair->Key, "classname"))
00744                                 continue;
00745                         if      (!stricmp(Epair->Key, "%typename%"))
00746                                 continue;
00747 
00748                         assert(stricmp(Epair->Key, "%defaultvalue%"));
00749 //
00750 // 18/11/00 Changed engine to accept float as well as geFloat
00751 //  in entity definition
00752 //
00753                         if(!stricmp(Epair->Value, "float"))
00754                                 TypeClass = geEntity_EntitySetFindClassByName(EntitySet, "geFloat");
00755                         else
00756                                 TypeClass = geEntity_EntitySetFindClassByName(EntitySet, Epair->Value);
00757 
00758                         if (!TypeClass)
00759                                 goto ExitWithError;             // Type not defined for this field!!!
00760 
00761                         Field = geEntity_FieldCreate(Epair->Key, Class->FieldSize, TypeClass);
00762 
00763                         if (!Field)
00764                                 goto ExitWithError;
00765 
00766                         if (!geEntity_ClassAddField(Class, Field))
00767                                 goto ExitWithError;
00768 
00769                         Epair = Epair->Next;
00770                         assert(Epair);
00771                         assert(!stricmp(Epair->Key, "%defaultvalue%"));
00772 
00773                 }       
00774         }
00775 
00776         return GE_TRUE;
00777 
00778         // ** ERROR **
00779         ExitWithError:
00780         {
00781                 if (Class)
00782                         geEntity_ClassDestroy(Class);
00783 
00784                 return GE_FALSE;
00785         }
00786 }
00787 
00788 //====================================================================================
00789 //      ParseTypedUserData
00790 //====================================================================================
00791 static geBoolean ParseClassUserData(geEntity_EntitySet *EntitySet, geEntity *Entity)
00792 {
00793         geEntity_Epair  *Epair;
00794         
00795         if (!Entity->Class)
00796                 return GE_TRUE;
00797         
00798         for (Epair = Entity->Epairs; Epair; Epair = Epair->Next)
00799         {
00800                 char                    *UData;
00801                 geEntity_Field  *Field;
00802 
00803                 // Skip %name% and classname keywords in entity
00804                 if      (!stricmp(Epair->Key, "classname"))
00805                         continue;
00806 
00807                 if (Epair->Key[0] == '%')               // Skip special names
00808                         continue;
00809 
00810                 // Find the field in this class
00811                 Field = geEntity_ClassFindFieldByName(Entity->Class, Epair->Key);
00812                 
00813                 if      (!Field)                
00814                         return GE_FALSE;
00815                         //continue;
00816 
00817                 UData = Entity->UserData;
00818 
00819                 switch (Field->TypeClass->Type)
00820                 {
00821                         double                  f;
00822                         double                  X, Y, Z;
00823                         int32                   M;
00824                         geEntity                *Ent;
00825 
00826                         case TYPE_INT:
00827                                 sscanf(Epair->Value, "%d", UData + Field->Offset);
00828                                 break;
00829 
00830                         case TYPE_FLOAT:
00831                                 sscanf(Epair->Value, "%lf", &f);
00832                                 *(geFloat *)(UData + Field->Offset) = (geFloat)f;
00833                                 break;
00834 
00835                         case TYPE_POINT:
00836                                 sscanf(Epair->Value, "%lf %lf %lf", &X, &Y, &Z);
00837                                 ((geVec3d *)(UData + Field->Offset))->X = (geFloat)X;
00838                                 ((geVec3d *)(UData + Field->Offset))->Y = (geFloat)Y;
00839                                 ((geVec3d *)(UData + Field->Offset))->Z = (geFloat)Z;
00840                                 break;
00841 
00842                         case TYPE_COLOR:
00843                                 sscanf(Epair->Value, "%lf %lf %lf", &X, &Y, &Z);
00844                                 ((GE_RGBA *)(UData + Field->Offset))->r = (geFloat)X;
00845                                 ((GE_RGBA *)(UData + Field->Offset))->g = (geFloat)Y;
00846                                 ((GE_RGBA *)(UData + Field->Offset))->b = (geFloat)Z;
00847                                 ((GE_RGBA *)(UData + Field->Offset))->a = 0.0f;
00848                                 break;
00849 
00850                         case TYPE_STRING:
00851                                 // Point to string in Epair
00852                                 *(char **)(UData + Field->Offset) = Epair->Value;
00853                                 break;
00854 
00855                         case TYPE_PTR:
00856                                 // Must be some arbitrary pointer definition the user had in the private section.
00857                                 // Always initialize these to NULL.
00858                                 *(void **)(UData + Field->Offset) = NULL;
00859                                 break;
00860 
00861                         case TYPE_MODEL:
00862 
00863                                 Ent = geEntity_EntitySetFindEntityByName(EntitySet, Epair->Value);
00864 
00865                                 if (!Ent)
00866                                 {
00867                                         geErrorLog_Add(GE_ERR_MODEL_NOT_FOUND, NULL);
00868                                         return GE_FALSE;
00869                                 }
00870 
00871                                 if (!geEntity_GetModelNumForKey(Ent, "Model", &M))
00872                                 {
00873                                         geErrorLog_Add(GE_ERR_MODEL_NOT_IN_ENTITY, NULL);
00874                                         return GE_FALSE;
00875                                 }
00876                         
00877                                 // Point their structure directly to the model
00878                                 *(geWorld_Model**)(UData + Field->Offset) = &GWorld->CurrentBSP->Models[M];
00879                         
00880                                 break;
00881 
00882                         case TYPE_STRUCT:
00883                                 Ent = geEntity_EntitySetFindEntityByName(EntitySet, Epair->Value);
00884 
00885                                 if      (!Ent)
00886                                         return GE_FALSE;
00887 
00888                                 // Point the void to the other entity
00889                                 *(void **)(UData + Field->Offset) = Ent->UserData;
00890 
00891                                 assert(*(void **)(UData + Field->Offset) != NULL);
00892                                 break;
00893 
00894                         default:
00895                                 //assert(!"Illegal top type");
00896                                 geErrorLog_Add(GE_ERR_INVALID_ENTITY_FIELD_TYPE, NULL);
00897                                 return GE_FALSE;
00898                 }
00899         }
00900 
00901         return GE_TRUE;
00902 }
00903 
00904 //====================================================================================
00905 //      ParseClassData
00906 //====================================================================================
00907 static geBoolean ParseClassData(geEntity_EntitySet *EntitySet)
00908 {
00909         geEntity_EntitySet      *Set;
00910         const char                      *Name;
00911 
00912         //
00913         //  Do this in two passes.  First pass, we setup the entities, and allocate all the user data.
00914         //  Second pass, we actually parse the user data.  This is so that we can resolve forward
00915         //  references in the user structures in the bsp file.
00916         //
00917 
00918         
00919         for (Set = EntitySet; Set; Set = Set->Next)
00920         {
00921                 geEntity                *Entity;
00922                 geEntity_Class  *Class;
00923 
00924                 Entity = Set->Entity;
00925 
00926                 Name = geEntity_GetStringForKey(Entity, "classname");
00927 
00928                 if (!Name)
00929                         continue;
00930                 
00931                 Class = geEntity_EntitySetFindClassByName(EntitySet, Name);
00932 
00933                 Entity->Class = NULL;
00934                 Entity->UserData = NULL;
00935 
00936                 if      (!Class)                // Oops, this entity will not show up, it was not %typedef%'d
00937                         continue;
00938 
00939                 // Let this entity remember it's type class
00940                 Entity->Class = Class;
00941                 // Make user data big enough to hold all possible data from class type
00942                 Entity->UserData = GE_RAM_ALLOCATE_ARRAY(char, Class->FieldSize);
00943                 
00944                 if      (!Entity->UserData)
00945                 {
00946                         geErrorLog_Add(GE_ERR_GET_ENTITY_DATA_ERROR, NULL);
00947                         return GE_FALSE;
00948                 }
00949                 
00950                 // Clear the userdata
00951                 memset(Entity->UserData, 0, Class->FieldSize);
00952         }
00953 
00954         for (Set = EntitySet; Set; Set = Set->Next)
00955         {
00956                 geEntity                *Entity;
00957 
00958                 Entity = Set->Entity;
00959 
00960                 Name = geEntity_GetStringForKey(Entity, "classname");
00961 
00962                 if (!Name)
00963                         continue;
00964                 
00965                 if (!ParseClassUserData(EntitySet, Entity))
00966                 {
00967                         geErrorLog_Add(GE_ERR_GET_ENTITY_DATA_ERROR, NULL);
00968                         return GE_FALSE;
00969                 }
00970         }
00971 
00972         return GE_TRUE;
00973 }
00974 
00975 //====================================================================================
00976 //      geEntity_EntitySetBuildClasses
00977 //====================================================================================
00978 geBoolean geEntity_EntitySetBuildClasses(geEntity_EntitySet *Set)
00979 {
00980         if (!BuildClassTypes(Set))
00981                 return GE_FALSE;
00982 
00983         if (!ParseClassData(Set))
00984                 return GE_FALSE;
00985 
00986         return GE_TRUE;
00987 }
00988 
00989 //====================================================================================
00990 //      geEntity_EntitySetLoadEntities
00991 //====================================================================================
00992 geBoolean geEntity_EntitySetLoadEntities(geEntity_EntitySet *EntitySet, geVFile *VFile)
00993 {
00994         int32           i, NumEntities;
00995 
00996         if (!geVFile_Read(VFile, &NumEntities, sizeof(int32)))
00997                 return GE_FALSE;
00998 
00999         for (i=0; i< NumEntities; i++)
01000         {
01001                 geEntity                *Entity;
01002                 int32                   e, NumEpairs;
01003 
01004                 // Create the entity
01005                 Entity = geEntity_Create();
01006 
01007                 if (!Entity)
01008                         return GE_FALSE;
01009 
01010                 // Add it to the main set
01011                 if (!geEntity_EntitySetAddEntity(EntitySet, Entity))
01012                         return GE_FALSE;
01013 
01014                 // Load epairs
01015                 if (!geVFile_Read(VFile, &NumEpairs, sizeof(int32)))
01016                         return GE_FALSE;
01017 
01018                 for (e=0; e<NumEpairs; e++)
01019                 {
01020                         geEntity_Epair  *Epair;
01021                         int32                   Size;
01022 
01023                         Epair = geEntity_EpairCreate();
01024 
01025                         if (!Epair)
01026                                 return GE_FALSE;
01027 
01028                         // Get the Key Size
01029                         if (!geVFile_Read(VFile, &Size, sizeof(int32)))
01030                                 return GE_FALSE;
01031 
01032                         Epair->Key = GE_RAM_ALLOCATE_ARRAY(char, Size);
01033 
01034                         if (!Epair->Key)
01035                                 return GE_FALSE;
01036 
01037                         // Read the key
01038                         if (!geVFile_Read(VFile, Epair->Key, sizeof(char)*Size))
01039                                 return GE_FALSE;
01040 
01041                         // Get the Value Size
01042                         if (!geVFile_Read(VFile, &Size, sizeof(int32)))
01043                                 return GE_FALSE;
01044 
01045                         Epair->Value = GE_RAM_ALLOCATE_ARRAY(char, Size);
01046 
01047                         if (!Epair->Value)
01048                                 return GE_FALSE;
01049 
01050                         // Read the Value
01051                         if (!geVFile_Read(VFile, Epair->Value, sizeof(char)*Size))
01052                                 return GE_FALSE;
01053 
01054                         // Add the epair to the entity
01055                         if (!geEntity_AddEpair(Entity, Epair))
01056                                 return GE_FALSE;
01057                 }
01058 
01059         }
01060 
01061         return GE_TRUE;
01062 
01063 }
01064 
01065 //====================================================================================
01066 //      geEntity_LoadEntitySet
01067 //====================================================================================
01068 geEntity_EntitySet *LoadEntitySet(const char *EntityData, int32 EntityDataSize)
01069 {
01070         geEntity_EntitySet              *EntitySet;
01071         geVFile_MemoryContext   Context;
01072         geVFile                                 *MemFile;
01073 
01074         // Default some NULLS here
01075         EntitySet = NULL;
01076         MemFile = NULL;
01077 
01078         // Setup the context for the memfile
01079         Context.Data = (void*)EntityData;
01080         Context.DataLength = EntityDataSize;
01081 
01082         MemFile = geVFile_OpenNewSystem(NULL, GE_VFILE_TYPE_MEMORY, NULL, &Context, GE_VFILE_OPEN_READONLY);
01083 
01084         if (!MemFile)
01085                 return FALSE;
01086 
01087         // Create the entityset
01088         EntitySet = geEntity_EntitySetCreate();
01089 
01090         if (!EntitySet)         // Out of memory!!
01091                 goto ExitWithError;
01092 
01093         EntitySet->OwnsEntities = GE_TRUE;              // So this set will be the one to free everything...
01094 
01095         if (!geEntity_EntitySetLoadEntities(EntitySet, MemFile))
01096                 goto ExitWithError;
01097 
01098         geVFile_Close(MemFile);
01099         MemFile = NULL;
01100                 
01101         if (!geEntity_EntitySetBuildClasses(EntitySet))
01102                 goto ExitWithError;
01103 
01104         return EntitySet;
01105 
01106         // ** ERROR **
01107         ExitWithError:
01108         {
01109                 if (EntitySet)
01110                         geEntity_EntitySetDestroy(EntitySet);
01111 
01112                 if (MemFile)
01113                         geVFile_Close(MemFile);
01114 
01115                 return NULL;
01116         }
01117 }

Generated on Tue Sep 30 12:35:42 2003 for GTestAndEngine by doxygen 1.3.2