00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "stdafx.h"
00023 #include "qe3.h"
00024 #include "io.h"
00025 #include "pakstuff.h"
00026
00027
00028 eclass_t *eclass = NULL;
00029 eclass_t *eclass_bad = NULL;
00030 char eclass_directory[1024];
00031
00032
00033 eclass_t *g_md3Cache = NULL;
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 void CleanEntityList(eclass_t *&pList)
00050 {
00051 while (pList)
00052 {
00053 eclass_t* pTemp = pList->next;
00054
00055 entitymodel *model = pList->model;
00056 while (model != NULL)
00057 {
00058 delete []model->pTriList;
00059 model = model->pNext;
00060 }
00061
00062 if (pList->modelpath)
00063 free(pList->modelpath);
00064 if (pList->skinpath)
00065 free(pList->skinpath);
00066
00067 free(pList->name);
00068 free(pList->comments);
00069 free(pList);
00070 pList = pTemp;
00071 }
00072
00073 pList = NULL;
00074
00075 }
00076
00077
00078 void CleanUpEntities()
00079 {
00080 CleanEntityList(eclass);
00081 CleanEntityList(g_md3Cache);
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101 if (eclass_bad)
00102 {
00103 free(eclass_bad->name);
00104 free(eclass_bad->comments);
00105 free(eclass_bad);
00106 eclass_bad = NULL;
00107 }
00108 }
00109
00110 void ExtendBounds(vec3_t v, vec3_t &vMin, vec3_t &vMax)
00111 {
00112 for (int i = 0 ;i < 3 ;i++)
00113 {
00114 vec_t f = v[i];
00115
00116 if (f < vMin[i])
00117 {
00118 vMin[i] = f;
00119 }
00120
00121 if (f > vMax[i])
00122 {
00123 vMax[i] = f;
00124 }
00125 }
00126 }
00127
00128
00129
00130
00131
00132 void LoadModel(const char *pLocation, eclass_t *e, vec3_t &vMin, vec3_t &vMax, entitymodel *&pModel, const char *pSkin)
00133 {
00134
00135
00136 char cPath[1024];
00137 char cSkin[1024];
00138 char cFullLocation[1024];
00139
00140
00141 vMin[0] = vMin[1] = vMin[2] = 99999;
00142 vMax[0] = vMax[1] = vMax[2] = -99999;
00143
00144 bool bMD3 = false;
00145 bool bASE = false;
00146
00147 strcpy( cFullLocation, pLocation );
00148
00149 if (strstr(pLocation, ".md3"))
00150 {
00151 bMD3 = true;
00152 }
00153 else if (strstr(pLocation, ".md2") != NULL)
00154 {
00155 sprintf( cFullLocation, "%stris.md2", pLocation);
00156 }
00157 else if (strstr(pLocation, ".ase") != NULL)
00158 {
00159 bASE = true;
00160 }
00161
00162 sprintf( cPath, "%s/%s", ValueForKey(g_qeglobals.d_project_entity, "basepath"), cFullLocation);
00163
00164 Sys_Printf("Loading model %s...", cPath);
00165 unsigned char* p = NULL;
00166 bool bOpen = (LoadFile(cPath, reinterpret_cast<void**>(&p)) > 0);
00167 if (!bOpen)
00168 {
00169 Sys_Printf(" failed. Trying PAK file...");
00170
00171 strcpy (cPath, cFullLocation);
00172 bOpen = (PakLoadAnyFile(cPath, reinterpret_cast<void**>(&p)) > 0);
00173 }
00174
00175 if (bOpen)
00176 {
00177 Sys_Printf(" successful.\n");
00178
00179 if (bASE)
00180 {
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202 }
00203
00204 if (bMD3)
00205 {
00206 md3Header_t header;
00207 md3Surface_t *pSurface;
00208 header = *(md3Header_t *)p;
00209 if (pSkin != NULL)
00210 {
00211 strcpy(cSkin, pSkin);
00212 }
00213 else
00214 {
00215 cSkin[0] = '\0';
00216 }
00217 int n = header.numFrames;
00218 pSurface = (md3Surface_t *) (p + header.ofsSurfaces);
00219 for (int z = 0; z < header.numSurfaces; z++ )
00220 {
00221 int nTris = pSurface->numTriangles;
00222
00223
00224
00225
00226 if (nTris > 0)
00227 {
00228 int nStart = 0;
00229 if (pModel->pTriList == NULL)
00230 {
00231 pModel->nModelPosition = 0;
00232 pModel->pTriList = new trimodel[nTris];
00233 pModel->nTriCount = nTris;
00234 }
00235 else
00236 {
00237
00238 int nNewCount = pModel->nTriCount + nTris;
00239 trimodel* pNewModels = new trimodel[nNewCount];
00240 for (int i = 0; i < pModel->nTriCount; i++)
00241 {
00242 memcpy(&pNewModels[i], &pModel->pTriList[i], sizeof(trimodel));
00243 }
00244 nStart = pModel->nTriCount;
00245 pModel->nTriCount = nNewCount;
00246
00247 delete [] pModel->pTriList;
00248 pModel->pTriList = pNewModels;
00249 }
00250
00251 md3Triangle_t *pTris = reinterpret_cast<md3Triangle_t*>((reinterpret_cast<unsigned char*>(pSurface) + pSurface->ofsTriangles));
00252 md3XyzNormal_t *pXyz = reinterpret_cast<md3XyzNormal_t*>((reinterpret_cast<unsigned char*>(pSurface) + pSurface->ofsXyzNormals));
00253 if (e->nFrame < pSurface->numFrames)
00254 {
00255 pXyz += (e->nFrame * pSurface->numVerts);
00256 }
00257
00258 md3St_t *pST = reinterpret_cast<md3St_t*>((reinterpret_cast<unsigned char*>(pSurface) + pSurface->ofsSt));
00259
00260 for (int i = 0; i < nTris; i++)
00261 {
00262 for (int k = 0; k < 3; k ++)
00263 {
00264 for (int j = 0; j < 3; j++)
00265 {
00266
00267 pModel->pTriList[nStart].v[k][j] = pXyz[pTris[i].indexes[k]].xyz[j] * MD3_XYZ_SCALE;
00268 }
00269 pModel->pTriList[nStart].st[k][0] = pST[pTris[i].indexes[k]].st[0];
00270 pModel->pTriList[nStart].st[k][1] = pST[pTris[i].indexes[k]].st[1];
00271 ExtendBounds (pModel->pTriList[nStart].v[k], vMin, vMax);
00272 }
00273 nStart++;
00274 }
00275
00276 }
00277
00278 md3Shader_t *pShader = reinterpret_cast<md3Shader_t*>((reinterpret_cast<unsigned char*>(pSurface) + pSurface->ofsShaders));
00279 sprintf (cPath, "%s/%s", ValueForKey(g_qeglobals.d_project_entity, "basepath"), pShader->name);
00280 strlwr(cPath);
00281 pModel->nTextureBind = Texture_LoadSkin(cPath, &pModel->nSkinWidth, &pModel->nSkinHeight);
00282 if (pModel->nTextureBind == -1)
00283 {
00284 Sys_Printf("Model skin load failed on texture %s\n", cPath);
00285 }
00286 pSurface = (md3Surface_t *) ((( char * ) pSurface) + pSurface->ofsEnd);
00287 pModel->pNext = reinterpret_cast<entitymodel_t*>(qmalloc(sizeof(entitymodel_t)));
00288 pModel = pModel->pNext;
00289 }
00290 }
00291 else
00292 {
00293
00294 dmdl_t model;
00295 daliasframe_t *f;
00296 unsigned char* pTris = p;
00297 dstvert_t *pST = NULL;
00298 int nTris = 0;
00299
00300
00301 memcpy(&model, p, sizeof(dmdl_t));
00302 f = (daliasframe_t*)(p + model.ofs_frames);
00303 pTris += model.ofs_tris;
00304 pST = reinterpret_cast<dstvert_t*>(p + model.ofs_st);
00305 nTris = model.num_tris;
00306
00307 if(pSkin)
00308 {
00309 strcpy (cSkin, pSkin);
00310 if ((cSkin[strlen(cSkin)-1] == '\\') || (cSkin[strlen(cSkin)-1] == '/'))
00311 strcat(cSkin, "skin.pcx\0");
00312 }
00313 else
00314 {
00315 strcpy(cSkin, (char *)(p + model.ofs_skins));
00316 }
00317
00318 sprintf (cPath, "%s/%s", ValueForKey(g_qeglobals.d_project_entity, "basepath"), cSkin);
00319 strlwr(cPath);
00320 pModel->nTextureBind = Texture_LoadSkin(cPath, &pModel->nSkinWidth, &pModel->nSkinHeight);
00321 if (pModel->nTextureBind == -1)
00322 {
00323 Sys_Printf("Model skin load failed on texture %s\n", cPath);
00324 }
00325 int nStart = 0;
00326 if (pModel->pTriList == NULL)
00327 {
00328 pModel->nModelPosition = 0;
00329 pModel->pTriList = new trimodel[nTris];
00330 pModel->nTriCount = nTris;
00331 }
00332 else
00333 {
00334
00335 int nNewCount = pModel->nTriCount + nTris;
00336 trimodel* pNewModels = new trimodel[nNewCount];
00337 for (int i = 0; i < pModel->nTriCount; i++)
00338 {
00339 memcpy(&pNewModels[i], &pModel->pTriList[i], sizeof(trimodel));
00340 }
00341 nStart = pModel->nTriCount;
00342 pModel->nTriCount = nNewCount;
00343 nTris = nNewCount;
00344 delete [] pModel->pTriList;
00345 pModel->pTriList = pNewModels;
00346 }
00347
00348 for (int i = nStart; i < nTris; i++)
00349 {
00350 dtriangle_t tri;
00351 memcpy(&tri, pTris, sizeof(dtriangle_t));
00352 for (int k = 0; k < 3; k ++)
00353 {
00354 for (int j = 0; j < 3; j++)
00355 {
00356 pModel->pTriList[i].v[k][j] = (f->verts[tri.index_xyz[k]].v[j] * f->scale[j] + f->translate[j]);
00357 }
00358
00359 pModel->pTriList[i].st[k][0] = pST[tri.index_st[k]].s / pModel->nSkinWidth;
00360 pModel->pTriList[i].st[k][1] = pST[tri.index_st[k]].t / pModel->nSkinHeight;;
00361 ExtendBounds (pModel->pTriList[i].v[k], vMin, vMax);
00362 }
00363 pTris += sizeof(dtriangle_t);
00364 }
00365 }
00366 free(p);
00367 }
00368 else
00369 {
00370 Sys_Printf(" failed.\n");
00371 }
00372
00373 #if 0
00374 if (pModel->pTriList != NULL && pModel->nTriCount > 0 && !bMD3)
00375 {
00376 if(fabs(vMin[2]) < ((vMax[2]-vMin[2]) / 10.0))
00377 pModel->nModelPosition = 1;
00378
00379 sprintf (cPath, "%s/%s", ValueForKey(g_qeglobals.d_project_entity, "basepath"), cSkin);
00380 pModel->nTextureBind = Texture_LoadSkin(cPath, &pModel->nSkinWidth, &pModel->nSkinHeight);
00381 if (pModel->nTextureBind == -1)
00382 {
00383
00384 strcpy (cPath, cSkin);
00385 pModel->nTextureBind = Texture_LoadSkin(cPath, &pModel->nSkinWidth, &pModel->nSkinHeight);
00386 }
00387 }
00388 #endif
00389
00390 }
00391
00392 void setSpecialLoad(eclass_t *e, const char* pWhat, char*& p)
00393 {
00394 CString str = e->comments;
00395 int n = str.Find(pWhat);
00396 if (n >= 0)
00397 {
00398 char* pText = e->comments + n + strlen(pWhat);
00399 if (*pText == '\"')
00400 pText++;
00401
00402 str = "";
00403 while (*pText != '\"' && *pText != '\0')
00404 {
00405 str += *pText;
00406 pText++;
00407 }
00408 if (str.GetLength() > 0)
00409 {
00410 p = strdup(str);
00411
00412 }
00413 }
00414 }
00415
00416 char *debugname;
00417
00418 eclass_t *Eclass_InitFromText (char *text)
00419 {
00420 char *t;
00421 int len;
00422 int r, i;
00423 char parms[256], *p;
00424 eclass_t *e;
00425 char color[128];
00426
00427 e = (eclass_t*)qmalloc(sizeof(*e));
00428 memset (e, 0, sizeof(*e));
00429
00430 text += strlen("/*QUAKED ");
00431
00432
00433 text = COM_Parse (text);
00434 e->name = (char*)qmalloc (strlen(com_token)+1);
00435 strcpy (e->name, com_token);
00436 debugname = e->name;
00437
00438
00439 r = sscanf (text," (%f %f %f)", &e->color[0], &e->color[1], &e->color[2]);
00440 if (r != 3)
00441 return e;
00442 sprintf (color, "(%f %f %f)", e->color[0], e->color[1], e->color[2]);
00443
00444 e->texdef.SetName(color);
00445
00446 while (*text != ')')
00447 {
00448 if (!*text)
00449 return e;
00450 text++;
00451 }
00452 text++;
00453
00454
00455 text = COM_Parse (text);
00456 if (com_token[0] == '(')
00457 {
00458 e->fixedsize = true;
00459 r = sscanf (text,"%f %f %f) (%f %f %f)", &e->mins[0], &e->mins[1], &e->mins[2],
00460 &e->maxs[0], &e->maxs[1], &e->maxs[2]);
00461 if (r != 6)
00462 return e;
00463
00464 for (i=0 ; i<2 ; i++)
00465 {
00466 while (*text != ')')
00467 {
00468 if (!*text)
00469 return e;
00470 text++;
00471 }
00472 text++;
00473 }
00474 }
00475 else
00476 {
00477 }
00478
00479
00480
00481
00482
00483 p = parms;
00484 while (*text && *text != '\n')
00485 *p++ = *text++;
00486 *p = 0;
00487 text++;
00488
00489
00490 p = parms;
00491 for (i=0 ; i<8 ; i++)
00492 {
00493 p = COM_Parse (p);
00494 if (!p)
00495 break;
00496 strcpy (e->flagnames[i], com_token);
00497 }
00498
00499
00500 for (t=text ; t[0] && !(t[0]=='*' && t[1]=='/') ; t++)
00501 ;
00502
00503
00504 len = t-text;
00505 e->comments = (char*)qmalloc (len+1);
00506 memcpy (e->comments, text, len);
00507 #if 0
00508 for (i=0 ; i<len ; i++)
00509 if (text[i] == '\n')
00510 e->comments[i] = '\r';
00511 else
00512 e->comments[i] = text[i];
00513 #endif
00514 e->comments[len] = 0;
00515
00516 setSpecialLoad(e, "model=", e->modelpath);
00517 setSpecialLoad(e, "skin=", e->skinpath);
00518 char *pFrame = NULL;
00519 setSpecialLoad(e, "frame=", pFrame);
00520 if (pFrame != NULL)
00521 {
00522 e->nFrame = atoi(pFrame);
00523 }
00524
00525 if(!e->skinpath)
00526 setSpecialLoad(e, "texture=", e->skinpath);
00527
00528
00529 e->nShowFlags = 0;
00530 if (strcmpi(e->name, "light") == 0)
00531 {
00532 e->nShowFlags |= ECLASS_LIGHT;
00533 }
00534
00535 if ( (strnicmp(e->name, "info_player", strlen("info_player")) == 0)
00536 ||(strnicmp(e->name, "path_corner", strlen("path_corner")) == 0)
00537 ||(strnicmp(e->name, "team_ctf", strlen("team_ctf")) == 0) )
00538 {
00539 e->nShowFlags |= ECLASS_ANGLE;
00540 }
00541 if (strcmpi(e->name, "path") == 0)
00542 {
00543 e->nShowFlags |= ECLASS_PATH;
00544 }
00545 if (strcmpi(e->name, "misc_model") == 0)
00546 {
00547 e->nShowFlags |= ECLASS_MISCMODEL;
00548 }
00549
00550
00551 return e;
00552 }
00553
00554 qboolean Eclass_hasModel(eclass_t *e, vec3_t &vMin, vec3_t &vMax)
00555 {
00556 if (e->modelpath != NULL)
00557 {
00558 if (e->model == NULL)
00559 {
00560 e->model = reinterpret_cast<entitymodel_t*>(qmalloc(sizeof(entitymodel_t)));
00561 }
00562 char *pModelBuff = strdup(e->modelpath);
00563 char *pSkinBuff = NULL;
00564 if (e->skinpath)
00565 {
00566 pSkinBuff = strdup(e->skinpath);
00567 }
00568
00569 CStringList Models;
00570 CStringList Skins;
00571 char* pToken = strtok(pModelBuff, ";\0");
00572 while (pToken != NULL)
00573 {
00574 Models.AddTail(pToken);
00575 pToken = strtok(NULL, ";\0");
00576 }
00577
00578 if (pSkinBuff != NULL)
00579 {
00580 pToken = strtok(pSkinBuff, ";\0");
00581 while (pToken != NULL)
00582 {
00583 Skins.AddTail(pToken);
00584 pToken = strtok(NULL, ";\0");
00585 }
00586 }
00587
00588 entitymodel *model = e->model;
00589 for (int i = 0; i < Models.GetCount(); i++)
00590 {
00591 char *pSkin = NULL;
00592 if (i < Skins.GetCount())
00593 {
00594 pSkin = Skins.GetAt(Skins.FindIndex(i)).GetBuffer(0);
00595 }
00596 LoadModel(Models.GetAt(Models.FindIndex(i)), e, vMin, vMax, model, pSkin);
00597 model->pNext = reinterpret_cast<entitymodel_t*>(qmalloc(sizeof(entitymodel_t)));
00598 model = model->pNext;
00599 }
00600
00601
00602
00603
00604 VectorSnap(vMin);
00605 VectorSnap(vMax);
00606
00607 if (vMax[0] - vMin[0] < 2)
00608 {
00609 vMin[0] -= 1;
00610 vMax[0] += 1;
00611 }
00612
00613 if (vMin[1] - vMax[1] < 2)
00614 {
00615 vMin[1] -= 1;
00616 vMax[1] += 1;
00617 }
00618
00619 if (vMax[2] - vMin[2] < 2)
00620 {
00621 vMax[2] -= 1;
00622 vMax[2] += 1;
00623 }
00624
00625 vec3_t vTemp;
00626 VectorAdd(vMin, vMax, vTemp);
00627 VectorScale(vTemp, 0.5, vTemp);
00628 model = e->model;
00629 while (model != NULL)
00630 {
00631 for (i = 0; i < model->nTriCount; i++)
00632 {
00633 for (int j = 0; j < 3; j++)
00634 {
00635 ;
00636 }
00637 }
00638 model = model->pNext;
00639 }
00640
00641 free(pModelBuff);
00642 free(e->modelpath);
00643 e->modelpath = NULL;
00644
00645 if(e->skinpath)
00646 {
00647 free(e->skinpath);
00648 e->skinpath = NULL;
00649 free(pSkinBuff);
00650 }
00651
00652 }
00653 return (e->model != NULL && e->model->nTriCount > 0);
00654 }
00655
00656
00657 void EClass_InsertSortedList(eclass_t *&pList, eclass_t *e)
00658 {
00659 eclass_t *s;
00660
00661 if (!pList)
00662 {
00663 pList = e;
00664 return;
00665 }
00666
00667
00668 s = pList;
00669 if (stricmp (e->name, s->name) < 0)
00670 {
00671 e->next = s;
00672 pList = e;
00673 return;
00674 }
00675
00676 do
00677 {
00678 if (!s->next || stricmp (e->name, s->next->name) < 0)
00679 {
00680 e->next = s->next;
00681 s->next = e;
00682 return;
00683 }
00684 s=s->next;
00685 } while (1);
00686 }
00687
00688
00689
00690
00691
00692
00693 void Eclass_InsertAlphabetized (eclass_t *e)
00694 {
00695 #if 1
00696 EClass_InsertSortedList(eclass, e);
00697 #else
00698 eclass_t *s;
00699
00700 if (!eclass)
00701 {
00702 eclass = e;
00703 return;
00704 }
00705
00706
00707 s = eclass;
00708 if (stricmp (e->name, s->name) < 0)
00709 {
00710 e->next = s;
00711 eclass = e;
00712 return;
00713 }
00714
00715 do
00716 {
00717 if (!s->next || stricmp (e->name, s->next->name) < 0)
00718 {
00719 e->next = s->next;
00720 s->next = e;
00721 return;
00722 }
00723 s=s->next;
00724 } while (1);
00725 #endif
00726 }
00727
00728
00729
00730
00731
00732
00733
00734
00735 qboolean parsing_single = false;
00736 qboolean eclass_found;
00737 eclass_t *eclass_e;
00738
00739 extern bool g_bBuildList;
00740 CString strDefFile;
00741
00742 void Eclass_ScanFile (char *filename)
00743 {
00744 int size;
00745 char *data;
00746 eclass_t *e;
00747 int i;
00748 char temp[1024];
00749
00750 QE_ConvertDOSToUnixName( temp, filename );
00751
00752 Sys_Printf ("ScanFile: %s\n", temp);
00753
00754
00755 size = LoadFile (filename, (void**)&data);
00756 eclass_found = false;
00757 for (i=0 ; i<size ; i++)
00758 if (!strncmp(data+i, "/*QUAKED",8))
00759 {
00760
00761
00762 if (g_bBuildList)
00763 {
00764 CString strDef = "";
00765 int j = i;
00766 while (1)
00767 {
00768 strDef += *(data+j);
00769 if (*(data+j) == '/' && *(data+j-1) == '*')
00770 break;
00771 j++;
00772 }
00773 strDef += "\r\n\r\n\r\n";
00774 strDefFile += strDef;
00775 }
00776
00777 e = Eclass_InitFromText (data+i);
00778 if (e)
00779 Eclass_InsertAlphabetized (e);
00780 else
00781 printf ("Error parsing: %s in %s\n",debugname, filename);
00782
00783
00784 eclass_e = e;
00785 eclass_found = true;
00786 if ( parsing_single )
00787 break;
00788 }
00789
00790 free (data);
00791 }
00792
00793
00794
00795 void Eclass_InitForSourceDirectory (char *path)
00796 {
00797 struct _finddata_t fileinfo;
00798 int handle;
00799 char filename[1024];
00800 char filebase[1024];
00801 char temp[1024];
00802 char *s;
00803
00804 QE_ConvertDOSToUnixName( temp, path );
00805
00806 Sys_Printf ("Eclass_InitForSourceDirectory: %s\n", temp );
00807
00808 strcpy (filebase, path);
00809 s = filebase + strlen(filebase)-1;
00810 while (*s != '\\' && *s != '/' && s!=filebase)
00811 s--;
00812 *s = 0;
00813
00814 CleanUpEntities();
00815 eclass = NULL;
00816
00817 if (g_bBuildList)
00818 strDefFile = "";
00819
00820 handle = _findfirst (path, &fileinfo);
00821 if (handle != -1)
00822 {
00823 do
00824 {
00825 sprintf (filename, "%s\\%s", filebase, fileinfo.name);
00826 Eclass_ScanFile (filename);
00827 } while (_findnext( handle, &fileinfo ) != -1);
00828
00829 _findclose (handle);
00830 }
00831
00832
00833 if (g_bBuildList)
00834 {
00835 CFile file;
00836 if (file.Open("c:\\entities.def", CFile::modeCreate | CFile::modeWrite))
00837 {
00838 file.Write(strDefFile.GetBuffer(0), strDefFile.GetLength());
00839 file.Close();
00840 }
00841 }
00842
00843
00844 eclass_bad = Eclass_InitFromText ("/*QUAKED UNKNOWN_CLASS (0 0.5 0) ?");
00845 }
00846
00847 eclass_t *Eclass_ForName (char *name, qboolean has_brushes)
00848 {
00849 eclass_t *e;
00850 char init[1024];
00851
00852 #ifdef _DEBUG
00853
00854 if (strcmp(name, "group_info")==0)
00855 Sys_Printf("WARNING: unexpected group_info entity in Eclass_ForName\n");
00856 #endif
00857
00858 if (!name)
00859 return eclass_bad;
00860
00861 for (e=eclass ; e ; e=e->next)
00862 if (!strcmp (name, e->name))
00863 return e;
00864
00865
00866 if (has_brushes)
00867 {
00868 sprintf (init, "/*QUAKED %s (0 0.5 0) ?\nNot found in source.\n", name);
00869 e = Eclass_InitFromText (init);
00870 }
00871 else
00872 {
00873 sprintf (init, "/*QUAKED %s (0 0.5 0) (-8 -8 -8) (8 8 8)\nNot found in source.\n", name);
00874 e = Eclass_InitFromText (init);
00875 }
00876
00877 Eclass_InsertAlphabetized (e);
00878
00879 return e;
00880 }
00881
00882
00883 eclass_t* GetCachedModel(entity_t *pEntity, const char *pName, vec3_t &vMin, vec3_t &vMax)
00884 {
00885
00886 eclass_t *e = NULL;
00887 if (pName == NULL || strlen(pName) == 0)
00888 {
00889 return NULL;
00890 }
00891
00892 for (e = g_md3Cache; e ; e = e->next)
00893 {
00894 if (!strcmp (pName, e->name))
00895 {
00896 pEntity->md3Class = e;
00897 VectorCopy(e->mins, vMin);
00898 VectorCopy(e->maxs, vMax);
00899 return e;
00900 }
00901 }
00902
00903 e = (eclass_t*)qmalloc(sizeof(*e));
00904 memset (e, 0, sizeof(*e));
00905 e->name = strdup(pName);
00906 e->modelpath = strdup(pName);
00907 e->skinpath = strdup(pName);
00908 char *p = strstr(e->skinpath, ".md3");
00909 if (p != NULL)
00910 {
00911 p++;
00912 strncpy(p, "tga", 3);
00913 }
00914 else
00915 {
00916 free(e->skinpath);
00917 e->skinpath = NULL;
00918 }
00919
00920 e->color[0] = e->color[2] = 0.85;
00921
00922 if (Eclass_hasModel(e, vMin, vMax))
00923 {
00924 EClass_InsertSortedList(g_md3Cache, e);
00925 VectorCopy(vMin, e->mins);
00926 VectorCopy(vMax, e->maxs);
00927 pEntity->md3Class = e;
00928 return e;
00929 }
00930
00931 return NULL;
00932 }