📄 entitytable.cpp
字号:
/****************************************************************************************/
/* EntityTable.cpp */
/* */
/* Author: Jim Mischel, Jeff Lomax */
/* Description: Entity code */
/* */
/* The contents of this file are subject to the Genesis3D Public License */
/* Version 1.01 (the "License"); you may not use this file except in */
/* compliance with the License. You may obtain a copy of the License at */
/* http://www.genesis3d.com */
/* */
/* Software distributed under the License is distributed on an "AS IS" */
/* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See */
/* the License for the specific language governing rights and limitations */
/* under the License. */
/* */
/* The Original Code is Genesis3D, released March 25, 1999. */
/*Genesis3D Version 1.1 released November 15, 1999 */
/* Copyright (C) 1999 WildTangent, Inc. All Rights Reserved */
/* */
/* Prepared for GenEdit-Classic ver. 0.5, Dec. 15, 2000 */
/****************************************************************************************/
#include "stdafx.h"
#include "EntityTable.h"
#include <assert.h>
#include <stdio.h>
#include "cparser.h"
#include "ram.h"
#include "util.h"
#include "FilePath.h"
#include "bitmap.h"
#include "array.h"
#include "vfile.h"
typedef struct
{
Type *pType;
geBitmap *pBitmap;
} TypeBmpEntry;
typedef struct
{
Array *pItems;
int nEntries;
} TypeBmpArray;
static TypeBmpArray *TypeBmpArray_Create (void)
{
TypeBmpArray *pList;
pList = GE_RAM_ALLOCATE_STRUCT (TypeBmpArray);
if (pList != NULL)
{
pList->pItems = Array_Create (100, sizeof (TypeBmpEntry));
if (pList->pItems != NULL)
{
pList->nEntries = 0;
}
else
{
geRam_Free (pList);
}
}
return pList;
}
static TypeBmpEntry *TypeBmpArray_GetItem (TypeBmpArray *pList, int i)
{
TypeBmpEntry *pEntry;
pEntry = (TypeBmpEntry *)Array_ItemPtr (pList->pItems, i);
return pEntry;
}
static void TypeBmpArray_Destroy (TypeBmpArray **ppList)
{
int i;
TypeBmpArray *pList;
pList = *ppList;
for (i = 0; i < pList->nEntries; ++i)
{
TypeBmpEntry *pEntry;
pEntry = TypeBmpArray_GetItem (pList, i);
geBitmap_Destroy (&pEntry->pBitmap);
}
Array_Destroy (&pList->pItems);
geRam_Free (*ppList);
}
static TypeBmpEntry *TypeBmpArray_Add (TypeBmpArray *pList, Type *pType, geBitmap *pBitmap)
{
TypeBmpEntry Entry;
if (pList->nEntries == Array_GetSize (pList->pItems))
{
Array_Resize (pList->pItems, 2*pList->nEntries);
}
Entry.pType = pType;
Entry.pBitmap = pBitmap;
Array_PutAt (pList->pItems, pList->nEntries, &Entry, sizeof (TypeBmpEntry));
++(pList->nEntries);
return TypeBmpArray_GetItem (pList, pList->nEntries-1);
}
static TypeBmpEntry *TypeBmpArray_Find (TypeBmpArray *pList, Type *pType)
{
int i;
for (i = 0; i < pList->nEntries; ++i)
{
TypeBmpEntry *pEntry;
pEntry = TypeBmpArray_GetItem (pList, i);
if (pEntry->pType == pType)
{
return pEntry;
}
}
return NULL;
}
struct tag_EntityTable
{
CParser *EntityInfo;
TypeBmpArray *BitmapCache;
};
const char EntityNameKey[] = "%name%";
static const char Unnamed[] = "Unnamed";
static const char ClassnameKey[] = "classname";
static const char TypenameKey[] = "%typename%";
/*
The editor and tools depend on certain entities existing and
having certain properties, and will fail horribly if those entities
are missing or not defined properly. So we put the definitions
here in the code to eliminate any possibility of there being a problem.
The names "BMP_LIGHT", etc. are the resource identifiers for these bitmaps!
*/
static const char FixedEntityDefinitions[] =
"// Light\n" // Light entity
"#pragma GE_Type(\"BMP_LIGHT\")\n"
"typedef struct tag_light\n"
"{\n"
"#pragma GE_Published\n"
"int light;\n"
"GE_RGBA color;\n"
"int style;\n"
"geVec3d origin;\n"
"#pragma GE_Origin(origin)\n"
"#pragma GE_DefaultValue(light, \"150\")\n"
"} light;\n"
"// SpotLight\n" // SpotLight entity
"#pragma GE_Type(\"BMP_SPOTLIGHT\")\n"
"typedef struct tag_spotlight\n"
"{\n"
"int DummyRadius;\n"
"#pragma GE_Published\n"
"int light;\n"
"GE_RGBA color;\n"
"int style;\n"
"geVec3d origin;\n"
"geVec3d angles;\n"
"int arc;\n"
"#pragma GE_Origin(origin)\n"
"#pragma GE_Radius(DummyRadius)\n"
"#pragma GE_DefaultValue(DummyRadius, \"150\")\n"
"#pragma GE_DefaultValue(light, \"150\")\n"
"#pragma GE_Angles(angles)\n"
"#pragma GE_DefaultValue(angles, \"0 0 0\")\n"
"#pragma GE_Arc(arc)\n"
"#pragma GE_DefaultValue(arc, \"45\")\n"
"} spotlight;\n"
"// Model origin\n" // model origin entity
"#pragma GE_Type(\"BMP_MODELORG\")\n"
"typedef struct tag_ModelOrigin\n"
"{\n"
"geVec3d origin;\n"
"#pragma GE_Origin(origin)\n"
"} ModelOrigin;\n"
"// Camera\n" // Camera entity
"#pragma GE_Type(\"BMP_CAMERA\")\n"
"typedef struct tag_Camera\n"
"{\n"
"geVec3d origin;\n"
"geVec3d angles;\n"
"#pragma GE_Origin(origin)\n"
"#pragma GE_Angles(angles)\n"
"#pragma GE_DefaultValue(angles, \"180 0 0\")\n"
"} Camera;\n"
"\0xFFFF"; // EOF required by parser
#pragma warning (disable:4100)
static void EntityTable_ParseErrorFunction
(
char const *File,
int Line,
char const *Buff
)
{
MessageBox (NULL, Buff, "GenEdit", MB_OK);
}
#pragma warning (default:4100)
EntityTable *EntityTable_Create (char const *DirName)
{
EntityTable *pTable;
BOOL NoErrors = GE_FALSE;
// Create the structure
pTable = GE_RAM_ALLOCATE_STRUCT (EntityTable);
if (pTable != NULL)
{
pTable->EntityInfo = NULL;
pTable->BitmapCache = TypeBmpArray_Create ();
if (pTable->BitmapCache != NULL)
{
pTable->EntityInfo = CParser_Init (EntityTable_ParseErrorFunction);
if (pTable->EntityInfo != NULL)
{
NoErrors = GE_TRUE;
}
}
}
if (NoErrors)
{
// and then initialize it
// Parse the built-in definitions...
CParser_ParseMemoryBlock (pTable->EntityInfo, FixedEntityDefinitions, strlen (FixedEntityDefinitions), "StandardDefs");
// The passed DirName can specify multiple directories, separated by commas.
// We need to parse all header files in all named directories.
char *PathList = Util_Strdup (DirName);
char *c;
c = strtok (PathList, ";");
while (c != NULL)
{
char EntityPathName[_MAX_PATH];
// Now find all .H files in the directory and send them to CParser...
HANDLE FindHandle;
WIN32_FIND_DATA FindData;
char FoundPath[_MAX_PATH];
strcpy (EntityPathName, c);
FilePath_SlashTerminate (EntityPathName, EntityPathName);
// copy path for working dir...
strcpy (FoundPath, EntityPathName);
// append "*.H" to entity path name...
strcat (EntityPathName, "*.H");
FindHandle = FindFirstFile (EntityPathName, &FindData);
if (FindHandle != INVALID_HANDLE_VALUE)
{
geBoolean FindResult;
do
{
/*
The cFileName member of the WIN32_FIND_DATA structure contains
just the file name, not the full path. So we have to prepend
the path before we do anything with the file...
*/
char FullFilePath[_MAX_PATH];
strcpy (FullFilePath, FoundPath);
strcat (FullFilePath, FindData.cFileName);
CParser_ParseFile (pTable->EntityInfo, FullFilePath);
FindResult = FindNextFile (FindHandle, &FindData);
} while (FindResult != 0);
FindClose (FindHandle);
}
c = strtok (NULL, ";");
}
geRam_Free (PathList);
}
if (NoErrors == GE_FALSE)
{
// some error. Clean up and exit.
EntityTable_Destroy (&pTable);
}
return pTable;
}
void EntityTable_Destroy (EntityTable **ppTable)
{
EntityTable *pTable = *ppTable;
if (pTable->EntityInfo != NULL)
{
CParser_Destroy (pTable->EntityInfo);
}
if (pTable->BitmapCache != NULL)
{
TypeBmpArray_Destroy (&pTable->BitmapCache);
}
geRam_Free (pTable);
*ppTable = NULL;
}
static Type *EntityTable_GetEntityTypeFromName
(
const EntityTable *pTable,
char const *pName
)
{
StructIter si;
Type *tp;
assert (pTable != NULL);
tp = CParser_GetFirstStruct (&si, pTable->EntityInfo);
while (tp != NULL)
{
const char *typeName;
typeName = CParser_GetTypeName (tp);
if (strcmp (pName, typeName) == 0)
{
break;
}
tp = CParser_GetNextStruct (&si);
}
return tp;
}
geBoolean EntityTable_IsValidEntityType
(
const EntityTable *pTable,
char const *pName
)
{
return (EntityTable_GetEntityTypeFromName (pTable, pName) != NULL);
}
typedef const char *(*CParser_GetSpecialFieldNameFcn)(Type *tp);
static geBoolean EntityTable_GetEntitySpecialFieldName
(
const EntityTable *pTable,
char const *pEntityName,
CString &ResultFieldName,
CParser_GetSpecialFieldNameFcn Callback
)
{
char const *szFieldName;
Type *pEntityType;
pEntityType = EntityTable_GetEntityTypeFromName (pTable, pEntityName);
if (pEntityType != NULL)
{
szFieldName = Callback (pEntityType);
if (szFieldName != NULL)
{
ResultFieldName = szFieldName;
return TRUE;
}
}
return FALSE;
}
geBoolean EntityTable_GetEntityOriginFieldName
(
const EntityTable *pTable,
char const *pEntityName,
CString &OriginFieldName
)
{
return EntityTable_GetEntitySpecialFieldName (pTable, pEntityName, OriginFieldName, CParser_GetOriginFieldName);
}
geBoolean EntityTable_GetEntityRadiusFieldName
(
const EntityTable *pTable,
char const *pEntityName,
CString &RadiusFieldName
)
{
return EntityTable_GetEntitySpecialFieldName (pTable, pEntityName, RadiusFieldName, CParser_GetRadiusFieldName);
}
geBoolean EntityTable_GetEntityAnglesFieldName
(
const EntityTable *pTable,
char const *pEntityName,
CString &AnglesFieldName
)
{
return EntityTable_GetEntitySpecialFieldName (pTable, pEntityName, AnglesFieldName, CParser_GetAnglesFieldName);
}
geBoolean EntityTable_GetEntityArcFieldName
(
const EntityTable *pTable,
char const *pEntityName,
CString &ArcFieldName
)
{
return EntityTable_GetEntitySpecialFieldName (pTable, pEntityName, ArcFieldName, CParser_GetArcFieldName);
}
char const *EntityTable_GetEntityFieldDoc
(
const EntityTable *pTable,
char const *pEntityName,
char const *pFieldName
)
{
Type *pEntityType;
pEntityType = EntityTable_GetEntityTypeFromName (pTable, pEntityName);
if (pEntityType != NULL)
{
return CParser_GetTypeFieldDocumentation (pTable->EntityInfo, pEntityType, pFieldName);
}
return NULL;
}
static geBoolean EntityTable_GetPropertyType
(
Type *tp,
char const *pKey,
TopType *pType
)
{
FieldIter fi;
int res;
int published;
TopType tt;
const char * typeName;
const char * fieldName;
const char * defaultValue;
res = CParser_GetFirstField(&fi, tp, &tt, &typeName, &fieldName, &published, &defaultValue);
while (res)
{
if (strcmp (pKey, fieldName) == 0)
{
*pType = tt;
return TRUE;
}
res = CParser_GetNextField(&fi, &tt, &typeName, &fieldName, &published, &defaultValue);
}
return FALSE;
}
geBoolean EntityTable_GetEntityPropertyType
(
const EntityTable *pTable,
char const *pEntityName,
char const *pPropertyName,
TopType *pType
)
{
Type *pEntityType;
pEntityType = EntityTable_GetEntityTypeFromName (pTable, pEntityName);
if (pEntityType == NULL)
{
return FALSE;
}
// and return the type for the particular property...
return EntityTable_GetPropertyType (pEntityType, pPropertyName, pType);
}
CString EntityTable_GetEntityPropertyTypeName
(
const EntityTable *pTable,
char const *pEntityName,
char const *pPropertyName
)
{
Type *pEntityType;
pEntityType = EntityTable_GetEntityTypeFromName (pTable, pEntityName);
if (pEntityType == NULL)
{
assert (0); // can't happen???
return "Invalid";
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -