[Gtkradiant] ECLASS.CPP: LoadModel() can now load RtCW .mdc files
TiCaL
gtkradiant@zerowing.idsoftware.com
Wed, 20 Mar 2002 16:50:48 +0800
This is a multi-part message in MIME format.
------=_NextPart_000_0013_01C1D02F.631A68C0
Content-Type: multipart/alternative;
boundary="----=_NextPart_001_0014_01C1D02F.631A68C0"
------=_NextPart_001_0014_01C1D02F.631A68C0
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
Hello,
I've just modified the LoadModel function to load .mdc as well as the =
.md3 model file format. It compiles fine but haven't had a chance to =
test it yet. Find the new ECLASS.cpp with the new version of LoadModel =
function and qfiles.h (MDC File specs) attached. I'm new to GtkRadiant =
programming so if I'm doing something wrong let me know :)
Regards,
TiCaL
------=_NextPart_001_0014_01C1D02F.631A68C0
Content-Type: text/html;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=3DContent-Type content=3D"text/html; =
charset=3Diso-8859-1">
<META content=3D"MSHTML 6.00.2713.1100" name=3DGENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=3D#fffcf0>
<DIV><FONT face=3DArial size=3D2>Hello,</FONT></DIV>
<DIV><FONT face=3DArial size=3D2>I've just modified the LoadModel =
function to load=20
.mdc as well as the .md3 model file format. It compiles fine but =
haven't=20
had a chance to test it yet. Find the new ECLASS.cpp with the new =
version of=20
LoadModel function and qfiles.h (MDC File specs) attached. I'm new to =
GtkRadiant=20
programming so if I'm doing something wrong let me know :)</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>Regards,</FONT></DIV>
<DIV><FONT face=3DArial size=3D2>TiCaL</FONT></DIV></BODY></HTML>
------=_NextPart_001_0014_01C1D02F.631A68C0--
------=_NextPart_000_0013_01C1D02F.631A68C0
Content-Type: application/octet-stream;
name="ECLASS.cpp"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="ECLASS.cpp"
/*
This code is based on source provided under the terms of the Id Software =
LIMITED USE SOFTWARE LICENSE AGREEMENT, a copy of which is included with =
the
GtkRadiant sources (see LICENSE_ID). If you did not receive a copy of=20
LICENSE_ID, please contact Id Software immediately at =
info@idsoftware.com.
All changes and additions to the original source which have been =
developed by
other contributors (see CONTRIBUTORS) are provided under the terms of =
the
license the contributors choose (see LICENSE), to the extent permitted =
by the
LICENSE_ID. If you did not receive a copy of the contributor license,
please contact the GtkRadiant maintainers at info@gtkradiant.com =
immediately.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS =
IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, =
THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR =
PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR =
ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL =
DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR =
SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED =
AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF =
THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "stdafx.h"
#include <sys/stat.h>
#if defined (__linux__) || defined (__APPLE__)
#include <dirent.h>
#endif
#include "assert.h"
eclass_t *eclass =3D NULL;
eclass_t *eclass_bad =3D NULL;
const vec3_t smallbox[2] =3D {{-8,-8,-8},{8,8,8}};
char eclass_directory[1024];
qboolean parsing_single =3D false;
eclass_t *eclass_e;
/*!
implementation of the EClass manager API
*/
eclass_t** Get_EClass_E()
{
return &eclass_e;
}
void Set_Eclass_Found(qboolean b)
{
eclass_found =3D b;
}
qboolean Get_Parsing_Single()
{
return parsing_single;
}
// md3 cache for misc_models
//eclass_t *g_md3Cache =3D NULL;
/*
the classname, color triple, and bounding box are parsed out of comments
A ? size means take the exact brush size.
/ *QUAKED <classname> (0 0 0) ?
/ *QUAKED <classname> (0 0 0) (-8 -8 -8) (8 8 8)
Flag names can follow the size description:
/ *QUAKED func_door (0 .5 .8) ? START_OPEN STONE_SOUND DOOR_DONT_LINK =
GOLD_KEY SILVER_KEY
*/
void CleanEntityList(eclass_t *&pList)
{
while (pList)
{
eclass_t* pTemp =3D pList->next;
entitymodel *model =3D pList->model;
while (model !=3D NULL)
{
delete []model->pTriList;
if (model->strSkin)
g_string_free( (GString *)model->strSkin, TRUE );
model->strSkin =3D NULL;
model =3D model->pNext;
}
=20
if (pList->modelpath)
free(pList->modelpath);
if (pList->skinpath) // PGM
free(pList->skinpath); // PGM
=20
free(pList->name);
free(pList->comments);
free(pList);
pList =3D pTemp;
}
pList =3D NULL;
}
void CleanUpEntities()
{
// NOTE: maybe some leak checks needed .. older versions of Radiant =
looked like they were freezing more stuff
CleanEntityList(eclass);
//CleanEntityList(g_md3Cache);
if (eclass_bad)
{
free(eclass_bad->name);
free(eclass_bad->comments);
free(eclass_bad);
eclass_bad =3D NULL;
}
}
void ExtendBounds(vec3_t v, vec3_t &vMin, vec3_t &vMax)
{
for (int i =3D 0 ;i < 3 ;i++)
{
vec_t f =3D v[i];
=09
if (f < vMin[i])
{
vMin[i] =3D f;
}
if (f > vMax[i])
{
vMax[i] =3D f;
}
}
}
void DecodeNormal(byte bytes[2], float normal[3])
{
//if (!bytes) return;
float lat, lng;
int a, b;
b =3D (int)bytes[0];
a =3D (int)bytes[1];
// decode the lat/lng normal to a 3 float normal
lat =3D (float)a * Q_PI/128.0f;
lng =3D (float)b * Q_PI/128.0f;
normal[0] =3D cos(lat) * sin(lng);
normal[1] =3D sin(lat) * sin(lng);
normal[2] =3D cos(lng);
}
// Take a pointer to a file location, a pointer to an eclass, an AABB, =
a pointer to an entitymodel
// Open the file using VFS
// Read each surface into an entitymodel and add the entitymodel to the =
front of a list
// return a pointer to the first model in the list
// TTimo: removed old support for .md2 and .ase
// NOTE: pSkin is no longer used, does nothing
// we expect the relative path to the .md3 file
// TiCaL: 20/03/2002 : added .mdc file support
entitymodel *LoadModel(const char *pLocation, eclass_t *e, vec3_t &vMin, =
vec3_t &vMax, entitymodel *pModel)
{
int i, j;
int nTris, nVerts;
int modeltype; /* TiCaL: MD3||MDC */
entitymodel *newModel;
=20
md3Triangle_t *pTris;=20
md3XyzNormal_t *pXyz;=20
md3St_t *pST;=20
=20
/* TiCaL: mdc file structs */
/* look at qfiles.h for MDC File specs */
mdcTriangle_t *pcTris;=20
mdcXyzNormal_t *pcXyz;
mdcSt_t *pcST;
=20
vMin[0] =3D vMin[1] =3D vMin[2] =3D g_MaxWorldCoord+1;
vMax[0] =3D vMax[1] =3D vMax[2] =3D g_MinWorldCoord-1;
=20
/* TiCaL: Find out what we are dealing with */
if (strstr(pLocation, ".md3"))
{
modeltype =3D MD3;
}
else if(strstr(pLocation, ".mdc"))
{
modeltype =3D MDC;
}
else
{
Sys_Printf("ERROR: unknown model type: %s\n", pLocation );
return pModel;
}
=20
unsigned char* p =3D NULL;
bool bOpen;
bOpen =3D (vfsLoadFile(pLocation, reinterpret_cast<void**>(&p)) > =
0);
if (bOpen)
Sys_Printf("Loaded model: %s\n", pLocation);
=20
if (bOpen)
{
=20
//TiCaL: If its a MD3 file do this
if(modeltype=3D=3DMD3)
{
md3Header_t header =3D *(md3Header_t *)p;
=20
// check for IDP3
int ident =3D LittleLong(header.ident);
if (ident !=3D MD3_IDENT)
{
Sys_Printf( "LoadModel: %s has wrong ident (%i should be =
%i)\n",
pLocation, ident, MD3_IDENT);
return pModel;
}
=20
md3Surface_t *pSurface =3D (md3Surface_t *) (p + =
header.ofsSurfaces);
=20
for (int z =3D 0; z < header.numSurfaces; z++ )
{
nTris =3D pSurface->numTriangles;
nVerts =3D pSurface->numVerts;
newModel =3D =
reinterpret_cast<entitymodel_t*>(qmalloc(sizeof(entitymodel_t)));
newModel->pNext =3D pModel;
pModel =3D newModel;
=20
if (nTris > 0)
{
pModel->nModelPosition =3D 0;
pModel->pTriList =3D new triindex[nTris];
pModel->pVertList =3D new vertmodel[nVerts];
//pModel->pVertListTF =3D new vertmodel[nVerts];
pModel->nTriCount =3D nTris;
pModel->numVerts =3D nVerts;
=20
pTris =3D =
reinterpret_cast<md3Triangle_t*>((reinterpret_cast<unsigned =
char*>(pSurface) + pSurface->ofsTriangles));
pXyz =3D =
reinterpret_cast<md3XyzNormal_t*>((reinterpret_cast<unsigned =
char*>(pSurface) + pSurface->ofsXyzNormals));
pST =3D =
reinterpret_cast<md3St_t*>((reinterpret_cast<unsigned char*>(pSurface) + =
pSurface->ofsSt));=20
=20
// not used?
if (e->nFrame < pSurface->numFrames)
{
pXyz +=3D (e->nFrame * pSurface->numVerts);
}
=20
// read verts into vertex list - xyz, st, normal
for (i =3D 0; i < nVerts; i++)
{
for (j =3D 0; j < 3; j++)
{
pModel->pVertList[i].v[j] =3D pXyz[i].xyz[j] =
* MD3_XYZ_SCALE;
}
ExtendBounds (pModel->pVertList[i].v, vMin, =
vMax);
pModel->pVertList[i].st[0] =3D pST[i].st[0];
pModel->pVertList[i].st[1] =3D pST[i].st[1];
DecodeNormal((byte *)&pXyz[i].normal, =
pModel->pVertList[i].normal);
}
=20
// copy md3 triangle index list to internal triangle =
index list - both types are struct { int indexes[3] };
memcpy(pModel->pTriList, pTris, =
(sizeof(md3Triangle_t) * nTris));
}
=20
=20
md3Shader_t *pShader =3D =
reinterpret_cast<md3Shader_t*>((reinterpret_cast<unsigned =
char*>(pSurface) + pSurface->ofsShaders));=20
pModel->nTextureBind =3D Texture_LoadSkin(pShader->name, =
&pModel->nSkinWidth, &pModel->nSkinHeight);
// we store the shader name, we need to reload it in =
sleep mode
pModel->strSkin =3D g_string_new(NULL);
g_string_assign( (GString *)pModel->strSkin, =
pShader->name );
if (pModel->nTextureBind =3D=3D -1)
{
Sys_Printf("Model skin load failed on texture %s\n", =
pShader->name);
}
=20
// increment pSurface
pSurface =3D (md3Surface_t *) ((( char * ) pSurface) + =
pSurface->ofsEnd);
}
vfsFreeFile(p);
}
//TiCaL : if its a MDC file do this
else if(modeltype=3D=3DMDC)
{
mdcHeader_t header =3D *(mdcHeader_t *)p;
=20
// check for IDPC
int ident =3D LittleLong(header.ident);
if (ident !=3D MDC_IDENT)
{
Sys_Printf( "LoadModel: %s has wrong ident (%i should be =
%i)\n",
pLocation, ident, MDC_IDENT);
return pModel;
}
=20
mdcSurface_t *pcSurface =3D (mdcSurface_t *) (p + =
header.ofsSurfaces);
=20
for (int z =3D 0; z < header.numSurfaces; z++ )
{
nTris =3D pcSurface->numTriangles;
nVerts =3D pcSurface->numVerts;
newModel =3D =
reinterpret_cast<entitymodel_t*>(qmalloc(sizeof(entitymodel_t)));
newModel->pNext =3D pModel;
pModel =3D newModel;
=20
if (nTris > 0)
{
pModel->nModelPosition =3D 0;
pModel->pTriList =3D new triindex[nTris];
pModel->pVertList =3D new vertmodel[nVerts];
pModel->nTriCount =3D nTris;
pModel->numVerts =3D nVerts;
=20
pcTris =3D =
reinterpret_cast<mdcTriangle_t*>((reinterpret_cast<unsigned =
char*>(pcSurface) + pcSurface->ofsTriangles));
pcXyz =3D =
reinterpret_cast<mdcXyzNormal_t*>((reinterpret_cast<unsigned =
char*>(pcSurface) + pcSurface->ofsXyzNormals));
pcST =3D =
reinterpret_cast<mdcSt_t*>((reinterpret_cast<unsigned char*>(pcSurface) =
+ pcSurface->ofsSt));=20
=20
// not used?
if (e->nFrame < =
pcSurface->numBaseFrames+pcSurface->numCompFrames)
{
pcXyz +=3D (e->nFrame * pcSurface->numVerts);
}
=20
// read verts into vertex list - xyz, st, normal
for (i =3D 0; i < nVerts; i++)
{
for (j =3D 0; j < 3; j++)
{
pModel->pVertList[i].v[j] =3D =
pcXyz[i].xyz[j] * MDC_XYZ_SCALE;
}
ExtendBounds (pModel->pVertList[i].v, vMin, =
vMax);
pModel->pVertList[i].st[0] =3D pcST[i].st[0];
pModel->pVertList[i].st[1] =3D pcST[i].st[1];
DecodeNormal((byte *)&pcXyz[i].normal, =
pModel->pVertList[i].normal);
}
=20
// copy mdc triangle index list to internal triangle =
index list - both types are struct { int indexes[3] };
memcpy(pModel->pTriList, pcTris, =
(sizeof(mdcTriangle_t) * nTris));
}
=20
=20
mdcShader_t *pcShader =3D =
reinterpret_cast<mdcShader_t*>((reinterpret_cast<unsigned =
char*>(pcSurface) + pcSurface->ofsShaders));=20
pModel->nTextureBind =3D =
Texture_LoadSkin(pcShader->name, &pModel->nSkinWidth, =
&pModel->nSkinHeight);
// we store the shader name, we need to reload it in =
sleep mode
pModel->strSkin =3D g_string_new(NULL);
g_string_assign( (GString *)pModel->strSkin, =
pcShader->name );
if (pModel->nTextureBind =3D=3D -1)
{
Sys_Printf("Model skin load failed on texture %s\n", =
pcShader->name);
}
=20
// increment pSurface
pcSurface =3D (mdcSurface_t *) ((( char * ) pcSurface) + =
pcSurface->ofsEnd);
}
vfsFreeFile(p);
}
}
//else model not found
else
{
Sys_Printf("NOT FOUND: %s\n", pLocation);
}
return pModel;
}
// check if this eclass has a model, and load it if necessary
qboolean Eclass_hasModel(eclass_t *e, vec3_t &vMin, vec3_t &vMax)
{
int i;
entitymodel *pModel;
char *pModelBuff, *pToken;
if (e->modelpath !=3D NULL) // an eclass has a valid modelpath only =
until the model is loaded
{
pModelBuff =3D strdup(e->modelpath);
GSList *Models =3D NULL, /* *Skins =3D NULL,*/ *lst;
pToken =3D strtok(pModelBuff, ";\0"); // reads model paths separated =
by ';' into a list
while (pToken !=3D NULL)
{
Models =3D g_slist_append (Models, strdup (pToken));
pToken =3D strtok(NULL, ";\0");
}
=20
#ifdef _DEBUG
if (e->model)
Sys_Printf("WARNING: unexpected e->model !=3D NULL in =
EClass_hasModel\n");
#endif
// for each md3 specified in modelpath
// result is one large entitymodel linked list, containing multiple =
md3surfaces from one or more md3s
//e->model =3D =
reinterpret_cast<entitymodel_t*>(qmalloc(sizeof(entitymodel_t)));
//entitymodel *model =3D e->model;
pModel =3D NULL;
for (i =3D 0, lst =3D Models; lst !=3D NULL; lst =3D g_slist_next =
(lst))
{
pModel =3D LoadModel((char*)lst->data, e, vMin, vMax, pModel);=20
}
e->model =3D pModel;
for (lst =3D Models; lst !=3D NULL; lst =3D g_slist_next (lst))
free (lst->data);
g_slist_free (Models);
// at this poitn vMin and vMax contain the min max of the model
// which needs to be centered at origin 0, 0, 0
VectorSnap(vMin);
VectorSnap(vMax);
if (vMax[0] - vMin[0] < 2)
{
vMin[0] -=3D 1;
vMax[0] +=3D 1;
}
if (vMin[1] - vMax[1] < 2)
{
vMin[1] -=3D 1;
vMax[1] +=3D 1;
}
if (vMax[2] - vMin[2] < 2)
{
vMax[2] -=3D 1;
vMax[2] +=3D 1;
}
free(pModelBuff);
free(e->modelpath);
e->modelpath =3D NULL; =20
}
return (e->model !=3D NULL && e->model->nTriCount > 0);
}
void EClass_InsertSortedList(eclass_t *&pList, eclass_t *e)
{
eclass_t *s;
=09
if (!pList)
{
pList =3D e;
return;
}
s =3D pList;
if (stricmp (e->name, s->name) < 0)
{
e->next =3D s;
pList =3D e;
return;
}
do
{
if (!s->next || stricmp (e->name, s->next->name) < 0)
{
e->next =3D s->next;
s->next =3D e;
return;
}
s=3Ds->next;
} while (1);
}
/*
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
Eclass_InsertAlphabetized
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
*/
void Eclass_InsertAlphabetized (eclass_t *e)
{
#if 1
EClass_InsertSortedList(eclass, e);
#else
eclass_t *s;
=09
if (!eclass)
{
eclass =3D e;
return;
}
s =3D eclass;
if (stricmp (e->name, s->name) < 0)
{
e->next =3D s;
eclass =3D e;
return;
}
do
{
if (!s->next || stricmp (e->name, s->next->name) < 0)
{
e->next =3D s->next;
s->next =3D e;
return;
}
s=3Ds->next;
} while (1);
#endif
}
void EClass_InitForFileList(GSList *pFiles, _EClassTable *pTable)
{
GSList *pFile =3D pFiles;
while (pFile)
{
// for a given name, we grab the first .def in the vfs
// this allows to override baseq3/scripts/entities.def for instance
int count;
char relPath[PATH_MAX];
strcpy(relPath, "scripts/");
strcat(relPath, (char*)pFile->data);
// FIXME TTimo =
http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=3D130
if (!vfsGetFullPath(relPath, 0))
{
Sys_FPrintf(SYS_ERR, "Failed to find the full path for \"%s\" in =
the VFS\n", relPath);
Sys_FPrintf(SYS_ERR, "did you hit bug =
http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=3D130 ?\n");
}
else
pTable->m_pfnEClass_ScanFile(vfsGetFullPath(relPath, 0));
pFile =3D pFile->next;
}
}
/*!
Manually create an eclass_t, for when no modules exist.
this replaces and centralizes the eclass_t allocation
*/
eclass_t * EClass_Create( const char *name, float col1, float col2, =
float col3, const vec3_t *mins, const vec3_t *maxs, const char *comments =
)
{
eclass_t *e;
char color[128];
e =3D (eclass_t*)malloc(sizeof(*e));
memset (e, 0, sizeof(*e));
e->name =3D strdup(name);
// grab the color, reformat as texture name
e->color[0] =3D col1;
e->color[1] =3D col2;
e->color[2] =3D col3;
sprintf (color, "(%f %f %f)", e->color[0], e->color[1], e->color[2]);
e->texdef.SetName(color);
// supplied size ?
if (mins && maxs)
{
// Hydra:
// If we set worldspawn to be a fixed-size all the textures are
// displayed as flat-shaded. This is a KLUDGE now that we have
// multiple game support as the worldspawn entity is game specific.
// Note that this is only ever fixed for the user if a definition
// for the worldspawn entity was not loaded, this can happen for
// several reasons:
// a) no entity definition plugin exists
// b) no entity definition files were found
// c) no entity definition file contained an entry for worldspawn.
if (stricmp(name,"worldspawn") !=3D 0) e->fixedsize =3D true;
// copy the sizes..
memcpy(e->mins,mins,sizeof(vec3_t));
memcpy(e->maxs,maxs,sizeof(vec3_t));
}
if (comments)
e->comments =3D strdup(comments);
else
{
e->comments =3D (char*)malloc(1);
e->comments[0] =3D '\0';
}
return e;
}
void Eclass_Init ()
{
CleanUpEntities();
eclass =3D NULL;
GSList *pFiles;
// read optional format
if (g_bHaveEClassExt)
{
pFiles =3D =
vfsGetFileList("scripts",g_EClassExtTable.m_pfnGet_Extension());
if (pFiles)
{
EClass_InitForFileList(pFiles, &g_EClassDefTable);
vfsClearFileDirList(&pFiles);
pFiles =3D NULL;
} =20
}
// read in all scripts/*.def
pFiles =3D =
vfsGetFileList("scripts",g_EClassDefTable.m_pfnGet_Extension());
if (pFiles)
{
EClass_InitForFileList(pFiles, &g_EClassDefTable);
vfsClearFileDirList(&pFiles);
pFiles =3D NULL;
}
else
Sys_FPrintf(SYS_ERR, "Didn't find any scripts/*.def files to load =
EClass information\n");
//NOTE: this call assumes the .def plugin is loaded, if it's not we =
get a crash when a brush is created/loaded
//To fix this issue replace this call with a function that manually =
builds an eclass_t.
//e.g. EClass_Create()
//eclass_bad =3D EClass_InitFromText("def","/*QUAKED UNKNOWN_CLASS (0 =
0.5 0) ?");
// Using EClass_Create()
eclass_bad =3D EClass_Create("UNKNOWN_CLASS" , 0, 0.5, =
0,NULL,NULL,NULL);
}
eclass_t *Eclass_ForName (char *name, qboolean has_brushes)
{
eclass_t *e;
char init[1024];
if (!name || *name =3D=3D '\0')
return eclass_bad;
#ifdef _DEBUG
// grouping stuff, not an eclass
if (strcmp(name, "group_info")=3D=3D0)
Sys_Printf("WARNING: unexpected group_info entity in =
Eclass_ForName\n");
#endif
if (!name)
return eclass_bad;
for (e=3Declass ; e ; e=3De->next)
if (!strcmp (name, e->name))
return e;
// create a new class for it
if (has_brushes)
{
// Using EClass_Create
// sprintf (init, "/*QUAKED %s (0 0.5 0) ?\nNot found in source.\n", =
name);
// e =3D EClass_InitFromText("def",init);
e =3D EClass_Create(name , 0, 0.5, 0,NULL,NULL,"Not found in =
source.");
}
else
{
// Using EClass_Create
// sprintf (init, "/*QUAKED %s (0 0.5 0) (-8 -8 -8) (8 8 8)\nNot found =
in source.\n", name);
// e =3D EClass_InitFromText("def",init);
e =3D EClass_Create(name , 0, 0.5, 0,&smallbox[0],&smallbox[1],"Not =
found in source.");
}
Eclass_InsertAlphabetized (e);
return e;
}
------=_NextPart_000_0013_01C1D02F.631A68C0
Content-Type: application/octet-stream;
name="qfiles.h"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="qfiles.h"
/*
This code is based on source provided under the terms of the Id Software =
LIMITED USE SOFTWARE LICENSE AGREEMENT, a copy of which is included with =
the
GtkRadiant sources (see LICENSE_ID). If you did not receive a copy of=20
LICENSE_ID, please contact Id Software immediately at =
info@idsoftware.com.
All changes and additions to the original source which have been =
developed by
other contributors (see CONTRIBUTORS) are provided under the terms of =
the
license the contributors choose (see LICENSE), to the extent permitted =
by the
LICENSE_ID. If you did not receive a copy of the contributor license,
please contact the GtkRadiant maintainers at info@gtkradiant.com =
immediately.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS =
IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, =
THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR =
PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR =
ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL =
DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR =
SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED =
AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF =
THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
//
// qfiles.h: quake file formats
// This file must be identical in the quake and utils directories
//
/*
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
.MD2 triangle model file format
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
*/
#define IDALIASHEADER (('2'<<24)+('P'<<16)+('D'<<8)+'I')
#define ALIAS_VERSION 8
#define MAX_TRIANGLES 4096
#define MAX_VERTS 2048
#define MAX_FRAMES 512
#define MAX_MD2SKINS 32
#define MAX_SKINNAME 64
typedef struct
{
short s;
short t;
} dstvert_t;
typedef struct=20
{
short index_xyz[3];
short index_st[3];
} dtriangle_t;
typedef struct
{
byte v[3]; // scaled byte to fit in frame mins/maxs
byte lightnormalindex;
} dtrivertx_t;
typedef struct
{
float scale[3]; // multiply byte verts by this
float translate[3]; // then add this
char name[16]; // frame name from grabbing
dtrivertx_t verts[1]; // variable sized
} daliasframe_t;
// the glcmd format:
// a positive integer starts a tristrip command, followed by that many
// vertex structures.
// a negative integer starts a trifan command, followed by -x vertexes
// a zero indicates the end of the command list.
// a vertex consists of a floating point s, a floating point t,
// and an integer vertex index.
typedef struct
{
int ident;
int version;
int skinwidth;
int skinheight;
int framesize; // byte size of each frame
int num_skins;
int num_xyz;
int num_st; // greater than num_xyz for seams
int num_tris;
int num_glcmds; // dwords in strip/fan command list
int num_frames;
int ofs_skins; // each skin is a MAX_SKINNAME string
int ofs_st; // byte offset from start for stverts
int ofs_tris; // offset for dtriangles
int ofs_frames; // offset for first frame
int ofs_glcmds;=09
int ofs_end; // end of file
} dmdl_t;
/*
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
.MD3 triangle model file format
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
*/
#define MD3_IDENT (('3'<<24)+('P'<<16)+('D'<<8)+'I')
#define MAX_QPATH 64 // max length of a quake game pathname
#define MD3_XYZ_SCALE (1.0/64)
#define MD3 0
typedef struct {
int ident;
int version;
char name[MAX_QPATH]; // model name
int flags;
int numFrames;
int numTags; =09
int numSurfaces;
int numSkins;
int ofsFrames; // offset for first frame
int ofsTags; // numFrames * numTags
int ofsSurfaces; // first surface, others follow
int ofsEnd; // end of file
} md3Header_t;
typedef struct {
int ident; //=20
char name[MAX_QPATH]; // polyset name
int flags;
int numFrames; // all surfaces in a model should have the same
int numShaders; // all surfaces in a model should have the same
int numVerts;
int numTriangles;
int ofsTriangles;
int ofsShaders; // offset from start of md3Surface_t
int ofsSt; // texture coords are common for all frames
int ofsXyzNormals; // numVerts * numFrames
int ofsEnd; // next surface follows
} md3Surface_t;
typedef struct {
char name[MAX_QPATH];
int shaderIndex; // for in-game use
} md3Shader_t;
typedef struct {
int indexes[3];
} md3Triangle_t;
typedef struct {
float st[2];
} md3St_t;
typedef struct {
short xyz[3];
short normal;
} md3XyzNormal_t;
typedef struct
{
float st[2];
int nVertIndex;
} glst_t;
typedef struct
{
int nCount;
int ObjectIndex;
glst_t GlSt;
} gl_t;
/*
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
.MDC triangle model file format
=20
=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
*/
#define MDC_IDENT (('C'<<24)+('P'<<16)+('D'<<8)+'I')
#define MDC_XYZ_SCALE (1.0/64)
#define MDC 1
typedef struct {
int ident;
int version;
=20
char name[MAX_QPATH]; // model name
=20
int flags;
=20
int numFrames;
int numTags; =09
int numSurfaces;
=20
int numSkins;
=20
int ofsFrames; // offset for first frame
int ofsTagNames; // tag names in a separate list
int ofsTags; // numFrames * numTags
int ofsSurfaces; // first surface, others follow
=20
int ofsEnd; // end of file
} mdcHeader_t;
typedef struct {
int ident; //=20
=20
char name[MAX_QPATH]; // polyset name
=20
int flags;
int numCompFrames; // number of compressed frames
int numBaseFrames; // number of base (uncompressed) frames
=20
int numShaders; // all surfaces in a model should have the same
int numVerts;
=20
int numTriangles;
int ofsTriangles;
=20
int ofsShaders; // offset from start of md3Surface_t
int ofsSt; // texture coords are common for all frames
int ofsXyzNormals; // numVerts * numFrames
int ofsCompXyzNormals; // compressed verts
=20
int ofsFrameBaseFrames; // animation frames (uncompressed)
int ofsFrameCompFrames; // animation frames (compressed)
=20
int ofsEnd; // next surface follows
=20
} mdcSurface_t;
typedef struct {
char name[MAX_QPATH];
int shaderIndex; // for in-game use
} mdcShader_t;
typedef struct {
int indexes[3];
} mdcTriangle_t;
typedef struct {
float st[2];
} mdcSt_t;
typedef struct {
short xyz[3];
short normal;
} mdcXyzNormal_t;
typedef struct {
float bboxMins[3]; //xyz
float bboxMaxs[3]; //xyz
float localOrigin[3]; //xyz
float radius;
char name[16]; // often creator
} mdcFrame_t;
/*
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
.SP2 sprite file format
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
*/
#define IDSPRITEHEADER (('2'<<24)+('S'<<16)+('D'<<8)+'I')
// little-endian "IDS2"
#define SPRITE_VERSION 2
typedef struct
{
int width, height;
int origin_x, origin_y; // raster coordinates inside pic
char name[MAX_SKINNAME]; // name of pcx file
} dsprframe_t;
typedef struct {
int ident;
int version;
int numframes;
dsprframe_t frames[1]; // variable sized
} dsprite_t;
/*
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
.WAL texture file format
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
*/
#define MIPLEVELS 4
#ifndef __MIPTEX_S_
#define __MIPTEX_S_
typedef struct miptex_s
{
char name[32];
unsigned width, height;
unsigned offsets[MIPLEVELS]; // four mip maps stored
char animname[32]; // next frame in animation chain
int flags;
int contents;
int value;
} miptex_t;
#endif
/*
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
.BSP file format
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
*/
#define IDBSPHEADER (('P'<<24)+('S'<<16)+('B'<<8)+'I')
// little-endian "IBSP"
#define BSPVERSION 36
// upper design bounds
// leaffaces, leafbrushes, planes, and verts are still bounded by
// 16 bit short limits
#define MAX_MAP_MODELS 1024
#define MAX_MAP_BRUSHES 8192
#define MAX_MAP_ENTITIES 2048
#define MAX_MAP_ENTSTRING 0x20000
#define MAX_MAP_TEXINFO 8192
#define MAX_MAP_PLANES 65536
#define MAX_MAP_NODES 65536
#define MAX_MAP_BRUSHSIDES 65536
#define MAX_MAP_LEAFS 65536
#define MAX_MAP_VERTS 65536
#define MAX_MAP_FACES 65536
#define MAX_MAP_LEAFFACES 65536
#define MAX_MAP_LEAFBRUSHES 65536
#define MAX_MAP_PORTALS 65536
#define MAX_MAP_EDGES 128000
#define MAX_MAP_SURFEDGES 256000
#define MAX_MAP_LIGHTING 0x200000
#define MAX_MAP_VISIBILITY 0x100000
// we are using g_MaxBrushSize now, cleanme
/* #define MAX_BRUSH_SIZE 8192 */
// key / value pair sizes
#define MAX_KEY 32
#define MAX_VALUE 1024
//=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
typedef struct
{
int fileofs, filelen;
} lump_t;
#define LUMP_ENTITIES 0
#define LUMP_PLANES 1
#define LUMP_VERTEXES 2
#define LUMP_VISIBILITY 3
#define LUMP_NODES 4
#define LUMP_TEXINFO 5
#define LUMP_FACES 6
#define LUMP_LIGHTING 7
#define LUMP_LEAFS 8
#define LUMP_LEAFFACES 9
#define LUMP_LEAFBRUSHES 10
#define LUMP_EDGES 11
#define LUMP_SURFEDGES 12
#define LUMP_MODELS 13
#define LUMP_BRUSHES 14
#define LUMP_BRUSHSIDES 15
#define LUMP_POP 16
#define HEADER_LUMPS 17
typedef struct
{
int ident;
int version;=09
lump_t lumps[HEADER_LUMPS];
} dheader_t;
typedef struct
{
float mins[3], maxs[3];
float origin[3]; // for sounds or lights
int headnode;
int firstface, numfaces; // submodels just draw faces
// without walking the bsp tree
} dmodel_t;
typedef struct
{
float point[3];
} dvertex_t;
// 0-2 are axial planes
#define PLANE_X 0
#define PLANE_Y 1
#define PLANE_Z 2
// 3-5 are non-axial planes snapped to the nearest
#define PLANE_ANYX 3
#define PLANE_ANYY 4
#define PLANE_ANYZ 5
// planes (x&~1) and (x&~1)+1 are allways opposites
typedef struct
{
float normal[3];
float dist;
int type; // PLANE_X - PLANE_ANYZ ?remove? trivial to regenerate
} dplane_t;
// contents flags are seperate bits
// a given brush can contribute multiple content bits
// multiple brushes can be in a single leaf
// lower bits are stronger, and will eat weaker brushes completely
#define CONTENTS_SOLID 1 // an eye is never valid in a solid
#define CONTENTS_WINDOW 2 // translucent, but not watery
#define CONTENTS_AUX 4
#define CONTENTS_LAVA 8
#define CONTENTS_SLIME 16
#define CONTENTS_WATER 32
#define CONTENTS_MIST 64
#define LAST_VISIBLE_CONTENTS 64
// remaining contents are non-visible, and don't eat brushes
#define CONTENTS_PLAYERCLIP 0x10000
#define CONTENTS_MONSTERCLIP 0x20000
// currents can be added to any other contents, and may be mixed
#define CONTENTS_CURRENT_0 0x40000
#define CONTENTS_CURRENT_90 0x80000
#define CONTENTS_CURRENT_180 0x100000
#define CONTENTS_CURRENT_270 0x200000
#define CONTENTS_CURRENT_UP 0x400000
#define CONTENTS_CURRENT_DOWN 0x800000
#define CONTENTS_ORIGIN 0x1000000 // removed before bsping an =
entity
#define CONTENTS_MONSTER 0x2000000 // should never be on a brush, =
only in game
#define CONTENTS_DEADMONSTER 0x4000000 // corpse
#define CONTENTS_DETAIL 0x8000000 // brushes to be added after =
vis leafs
#define CONTENTS_TRANSLUCENT 0x10000000 // auto set if any surface has =
trans
#define CONTENTS_LADDER 0x20000000 // ladder
#define CONTENTS_NEGATIVE_CURVE 0x40000000 // reverse inside / outside
#define CONTENTS_KEEP (CONTENTS_DETAIL | CONTENTS_NEGATIVE_CURVE)
typedef struct
{
int planenum;
int children[2]; // negative numbers are -(leafs+1), not nodes
short mins[3]; // for frustom culling
short maxs[3];
unsigned short firstface;
unsigned short numfaces; // counting both sides
} dnode_t;
typedef struct texinfo_s
{
float vecs[2][4]; // [s/t][xyz offset]
int flags; // miptex flags + overrides
int value; // light emission, etc
char texture[32]; // texture name (textures/*.wal)
int nexttexinfo; // for animations, -1 =3D end of chain
} texinfo_t;
#define SURF_LIGHT 0x1 // value will hold the light strength
#define SURF_SLICK 0x2 // effects game physics
#define SURF_SKY 0x4 // don't draw, but add to skybox
#define SURF_WARP 0x8 // turbulent water warp
#define SURF_TRANS33 0x10
#define SURF_TRANS66 0x20
#define SURF_FLOWING 0x40 // scroll towards angle
#define SURF_NODRAW 0x80 // don't bother referencing the texture
#define SURF_PATCH 0x20000000
#define SURF_CURVE_FAKE 0x40000000
#define SURF_CURVE 0x80000000
#define SURF_KEEP (SURF_CURVE | SURF_CURVE_FAKE | SURF_PATCH)
// note that edge 0 is never used, because negative edge nums are used =
for
// counterclockwise use of the edge in a face
typedef struct
{
unsigned short v[2]; // vertex numbers
} dedge_t;
#define MAXLIGHTMAPS 4
typedef struct
{
unsigned short planenum;
short side;
int firstedge; // we must support > 64k edges
short numedges;=09
short texinfo;
// lighting info
byte styles[MAXLIGHTMAPS];
int lightofs; // start of [numstyles*surfsize] samples
} dface_t;
typedef struct
{
int contents; // OR of all brushes (not needed?)
int pvsofs; // -1 =3D no info
int phsofs; // -1 =3D no info
short mins[3]; // for frustum culling
short maxs[3];
unsigned short firstleafface;
unsigned short numleaffaces;
unsigned short firstleafbrush;
unsigned short numleafbrushes;
} dleaf_t;
typedef struct
{
unsigned short planenum; // facing out of the leaf
short texinfo;
} dbrushside_t;
typedef struct
{
int firstside;
int numsides;
int contents;
} dbrush_t;
#define ANGLE_UP -1
#define ANGLE_DOWN -2
------=_NextPart_000_0013_01C1D02F.631A68C0--