model.c 24 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138
  1. /*
  2. Copyright (C) 1996-1997 Id Software, Inc.
  3. This program is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU General Public License
  5. as published by the Free Software Foundation; either version 2
  6. of the License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. See the GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  14. */
  15. // models.c -- model loading and caching
  16. // models are the only shared resource between a client and server running
  17. // on the same machine.
  18. #include "qwsvdef.h"
  19. model_t *loadmodel;
  20. char loadname[32]; // for hunk tags
  21. void Mod_LoadSpriteModel (model_t *mod, void *buffer);
  22. void Mod_LoadBrushModel (model_t *mod, void *buffer);
  23. void Mod_LoadAliasModel (model_t *mod, void *buffer);
  24. model_t *Mod_LoadModel (model_t *mod, qboolean crash);
  25. byte mod_novis[MAX_MAP_LEAFS/8];
  26. #define MAX_MOD_KNOWN 256
  27. model_t mod_known[MAX_MOD_KNOWN];
  28. int mod_numknown;
  29. texture_t r_notexture_mip;
  30. unsigned *model_checksum;
  31. /*
  32. ===============
  33. Mod_Init
  34. ===============
  35. */
  36. void Mod_Init (void)
  37. {
  38. memset (mod_novis, 0xff, sizeof(mod_novis));
  39. }
  40. /*
  41. ===============
  42. Mod_PointInLeaf
  43. ===============
  44. */
  45. mleaf_t *Mod_PointInLeaf (vec3_t p, model_t *model)
  46. {
  47. mnode_t *node;
  48. float d;
  49. mplane_t *plane;
  50. if (!model || !model->nodes)
  51. SV_Error ("Mod_PointInLeaf: bad model");
  52. node = model->nodes;
  53. while (1)
  54. {
  55. if (node->contents < 0)
  56. return (mleaf_t *)node;
  57. plane = node->plane;
  58. d = DotProduct (p,plane->normal) - plane->dist;
  59. if (d > 0)
  60. node = node->children[0];
  61. else
  62. node = node->children[1];
  63. }
  64. return NULL; // never reached
  65. }
  66. /*
  67. ===================
  68. Mod_DecompressVis
  69. ===================
  70. */
  71. byte *Mod_DecompressVis (byte *in, model_t *model)
  72. {
  73. static byte decompressed[MAX_MAP_LEAFS/8];
  74. int c;
  75. byte *out;
  76. int row;
  77. row = (model->numleafs+7)>>3;
  78. out = decompressed;
  79. #if 0
  80. memcpy (out, in, row);
  81. #else
  82. if (!in)
  83. { // no vis info, so make all visible
  84. while (row)
  85. {
  86. *out++ = 0xff;
  87. row--;
  88. }
  89. return decompressed;
  90. }
  91. do
  92. {
  93. if (*in)
  94. {
  95. *out++ = *in++;
  96. continue;
  97. }
  98. c = in[1];
  99. in += 2;
  100. while (c)
  101. {
  102. *out++ = 0;
  103. c--;
  104. }
  105. } while (out - decompressed < row);
  106. #endif
  107. return decompressed;
  108. }
  109. byte *Mod_LeafPVS (mleaf_t *leaf, model_t *model)
  110. {
  111. if (leaf == model->leafs)
  112. return mod_novis;
  113. return Mod_DecompressVis (leaf->compressed_vis, model);
  114. }
  115. /*
  116. ===================
  117. Mod_ClearAll
  118. ===================
  119. */
  120. void Mod_ClearAll (void)
  121. {
  122. int i;
  123. model_t *mod;
  124. for (i=0 , mod=mod_known ; i<mod_numknown ; i++, mod++)
  125. if (mod->type != mod_alias)
  126. mod->needload = true;
  127. }
  128. /*
  129. ==================
  130. Mod_FindName
  131. ==================
  132. */
  133. model_t *Mod_FindName (char *name)
  134. {
  135. int i;
  136. model_t *mod;
  137. if (!name[0])
  138. SV_Error ("Mod_ForName: NULL name");
  139. //
  140. // search the currently loaded models
  141. //
  142. for (i=0 , mod=mod_known ; i<mod_numknown ; i++, mod++)
  143. if (!strcmp (mod->name, name) )
  144. break;
  145. if (i == mod_numknown)
  146. {
  147. if (mod_numknown == MAX_MOD_KNOWN)
  148. SV_Error ("mod_numknown == MAX_MOD_KNOWN");
  149. strcpy (mod->name, name);
  150. mod->needload = true;
  151. mod_numknown++;
  152. }
  153. return mod;
  154. }
  155. /*
  156. ==================
  157. Mod_LoadModel
  158. Loads a model into the cache
  159. ==================
  160. */
  161. model_t *Mod_LoadModel (model_t *mod, qboolean crash)
  162. {
  163. void *d;
  164. unsigned *buf;
  165. byte stackbuf[1024]; // avoid dirtying the cache heap
  166. if (!mod->needload)
  167. {
  168. if (mod->type == mod_alias)
  169. {
  170. d = Cache_Check (&mod->cache);
  171. if (d)
  172. return mod;
  173. }
  174. else
  175. return mod; // not cached at all
  176. }
  177. //
  178. // load the file
  179. //
  180. buf = (unsigned *)COM_LoadStackFile (mod->name, stackbuf, sizeof(stackbuf));
  181. if (!buf)
  182. {
  183. if (crash)
  184. SV_Error ("Mod_NumForName: %s not found", mod->name);
  185. return NULL;
  186. }
  187. //
  188. // allocate a new model
  189. //
  190. COM_FileBase (mod->name, loadname);
  191. loadmodel = mod;
  192. //
  193. // fill it in
  194. //
  195. // call the apropriate loader
  196. mod->needload = false;
  197. Mod_LoadBrushModel (mod, buf);
  198. return mod;
  199. }
  200. /*
  201. ==================
  202. Mod_ForName
  203. Loads in a model for the given name
  204. ==================
  205. */
  206. model_t *Mod_ForName (char *name, qboolean crash)
  207. {
  208. model_t *mod;
  209. mod = Mod_FindName (name);
  210. return Mod_LoadModel (mod, crash);
  211. }
  212. /*
  213. ===============================================================================
  214. BRUSHMODEL LOADING
  215. ===============================================================================
  216. */
  217. byte *mod_base;
  218. /*
  219. =================
  220. Mod_LoadTextures
  221. =================
  222. */
  223. void Mod_LoadTextures (lump_t *l)
  224. {
  225. int i, j, pixels, num, max, altmax;
  226. miptex_t *mt;
  227. texture_t *tx, *tx2;
  228. texture_t *anims[10];
  229. texture_t *altanims[10];
  230. dmiptexlump_t *m;
  231. if (!l->filelen)
  232. {
  233. loadmodel->textures = NULL;
  234. return;
  235. }
  236. m = (dmiptexlump_t *)(mod_base + l->fileofs);
  237. m->nummiptex = LittleLong (m->nummiptex);
  238. loadmodel->numtextures = m->nummiptex;
  239. loadmodel->textures = Hunk_AllocName (m->nummiptex * sizeof(*loadmodel->textures) , loadname);
  240. for (i=0 ; i<m->nummiptex ; i++)
  241. {
  242. m->dataofs[i] = LittleLong(m->dataofs[i]);
  243. if (m->dataofs[i] == -1)
  244. continue;
  245. mt = (miptex_t *)((byte *)m + m->dataofs[i]);
  246. mt->width = LittleLong (mt->width);
  247. mt->height = LittleLong (mt->height);
  248. for (j=0 ; j<MIPLEVELS ; j++)
  249. mt->offsets[j] = LittleLong (mt->offsets[j]);
  250. if ( (mt->width & 15) || (mt->height & 15) )
  251. SV_Error ("Texture %s is not 16 aligned", mt->name);
  252. pixels = mt->width*mt->height/64*85;
  253. tx = Hunk_AllocName (sizeof(texture_t) +pixels, loadname );
  254. loadmodel->textures[i] = tx;
  255. memcpy (tx->name, mt->name, sizeof(tx->name));
  256. tx->width = mt->width;
  257. tx->height = mt->height;
  258. for (j=0 ; j<MIPLEVELS ; j++)
  259. tx->offsets[j] = mt->offsets[j] + sizeof(texture_t) - sizeof(miptex_t);
  260. // the pixels immediately follow the structures
  261. memcpy ( tx+1, mt+1, pixels);
  262. }
  263. //
  264. // sequence the animations
  265. //
  266. for (i=0 ; i<m->nummiptex ; i++)
  267. {
  268. tx = loadmodel->textures[i];
  269. if (!tx || tx->name[0] != '+')
  270. continue;
  271. if (tx->anim_next)
  272. continue; // allready sequenced
  273. // find the number of frames in the animation
  274. memset (anims, 0, sizeof(anims));
  275. memset (altanims, 0, sizeof(altanims));
  276. max = tx->name[1];
  277. altmax = 0;
  278. if (max >= 'a' && max <= 'z')
  279. max -= 'a' - 'A';
  280. if (max >= '0' && max <= '9')
  281. {
  282. max -= '0';
  283. altmax = 0;
  284. anims[max] = tx;
  285. max++;
  286. }
  287. else if (max >= 'A' && max <= 'J')
  288. {
  289. altmax = max - 'A';
  290. max = 0;
  291. altanims[altmax] = tx;
  292. altmax++;
  293. }
  294. else
  295. SV_Error ("Bad animating texture %s", tx->name);
  296. for (j=i+1 ; j<m->nummiptex ; j++)
  297. {
  298. tx2 = loadmodel->textures[j];
  299. if (!tx2 || tx2->name[0] != '+')
  300. continue;
  301. if (strcmp (tx2->name+2, tx->name+2))
  302. continue;
  303. num = tx2->name[1];
  304. if (num >= 'a' && num <= 'z')
  305. num -= 'a' - 'A';
  306. if (num >= '0' && num <= '9')
  307. {
  308. num -= '0';
  309. anims[num] = tx2;
  310. if (num+1 > max)
  311. max = num + 1;
  312. }
  313. else if (num >= 'A' && num <= 'J')
  314. {
  315. num = num - 'A';
  316. altanims[num] = tx2;
  317. if (num+1 > altmax)
  318. altmax = num+1;
  319. }
  320. else
  321. SV_Error ("Bad animating texture %s", tx->name);
  322. }
  323. #define ANIM_CYCLE 2
  324. // link them all together
  325. for (j=0 ; j<max ; j++)
  326. {
  327. tx2 = anims[j];
  328. if (!tx2)
  329. SV_Error ("Missing frame %i of %s",j, tx->name);
  330. tx2->anim_total = max * ANIM_CYCLE;
  331. tx2->anim_min = j * ANIM_CYCLE;
  332. tx2->anim_max = (j+1) * ANIM_CYCLE;
  333. tx2->anim_next = anims[ (j+1)%max ];
  334. if (altmax)
  335. tx2->alternate_anims = altanims[0];
  336. }
  337. for (j=0 ; j<altmax ; j++)
  338. {
  339. tx2 = altanims[j];
  340. if (!tx2)
  341. SV_Error ("Missing frame %i of %s",j, tx->name);
  342. tx2->anim_total = altmax * ANIM_CYCLE;
  343. tx2->anim_min = j * ANIM_CYCLE;
  344. tx2->anim_max = (j+1) * ANIM_CYCLE;
  345. tx2->anim_next = altanims[ (j+1)%altmax ];
  346. if (max)
  347. tx2->alternate_anims = anims[0];
  348. }
  349. }
  350. }
  351. /*
  352. =================
  353. Mod_LoadLighting
  354. =================
  355. */
  356. void Mod_LoadLighting (lump_t *l)
  357. {
  358. if (!l->filelen)
  359. {
  360. loadmodel->lightdata = NULL;
  361. return;
  362. }
  363. loadmodel->lightdata = Hunk_AllocName ( l->filelen, loadname);
  364. memcpy (loadmodel->lightdata, mod_base + l->fileofs, l->filelen);
  365. }
  366. /*
  367. =================
  368. Mod_LoadVisibility
  369. =================
  370. */
  371. void Mod_LoadVisibility (lump_t *l)
  372. {
  373. if (!l->filelen)
  374. {
  375. loadmodel->visdata = NULL;
  376. return;
  377. }
  378. loadmodel->visdata = Hunk_AllocName ( l->filelen, loadname);
  379. memcpy (loadmodel->visdata, mod_base + l->fileofs, l->filelen);
  380. }
  381. /*
  382. =================
  383. Mod_LoadEntities
  384. =================
  385. */
  386. void Mod_LoadEntities (lump_t *l)
  387. {
  388. if (!l->filelen)
  389. {
  390. loadmodel->entities = NULL;
  391. return;
  392. }
  393. loadmodel->entities = Hunk_AllocName ( l->filelen, loadname);
  394. memcpy (loadmodel->entities, mod_base + l->fileofs, l->filelen);
  395. }
  396. /*
  397. =================
  398. Mod_LoadVertexes
  399. =================
  400. */
  401. void Mod_LoadVertexes (lump_t *l)
  402. {
  403. dvertex_t *in;
  404. mvertex_t *out;
  405. int i, count;
  406. in = (void *)(mod_base + l->fileofs);
  407. if (l->filelen % sizeof(*in))
  408. SV_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
  409. count = l->filelen / sizeof(*in);
  410. out = Hunk_AllocName ( count*sizeof(*out), loadname);
  411. loadmodel->vertexes = out;
  412. loadmodel->numvertexes = count;
  413. for ( i=0 ; i<count ; i++, in++, out++)
  414. {
  415. out->position[0] = LittleFloat (in->point[0]);
  416. out->position[1] = LittleFloat (in->point[1]);
  417. out->position[2] = LittleFloat (in->point[2]);
  418. }
  419. }
  420. /*
  421. =================
  422. Mod_LoadSubmodels
  423. =================
  424. */
  425. void Mod_LoadSubmodels (lump_t *l)
  426. {
  427. dmodel_t *in;
  428. dmodel_t *out;
  429. int i, j, count;
  430. in = (void *)(mod_base + l->fileofs);
  431. if (l->filelen % sizeof(*in))
  432. SV_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
  433. count = l->filelen / sizeof(*in);
  434. out = Hunk_AllocName ( count*sizeof(*out), loadname);
  435. loadmodel->submodels = out;
  436. loadmodel->numsubmodels = count;
  437. for ( i=0 ; i<count ; i++, in++, out++)
  438. {
  439. for (j=0 ; j<3 ; j++)
  440. { // spread the mins / maxs by a pixel
  441. out->mins[j] = LittleFloat (in->mins[j]) - 1;
  442. out->maxs[j] = LittleFloat (in->maxs[j]) + 1;
  443. out->origin[j] = LittleFloat (in->origin[j]);
  444. }
  445. for (j=0 ; j<MAX_MAP_HULLS ; j++)
  446. out->headnode[j] = LittleLong (in->headnode[j]);
  447. out->visleafs = LittleLong (in->visleafs);
  448. out->firstface = LittleLong (in->firstface);
  449. out->numfaces = LittleLong (in->numfaces);
  450. }
  451. }
  452. /*
  453. =================
  454. Mod_LoadEdges
  455. =================
  456. */
  457. void Mod_LoadEdges (lump_t *l)
  458. {
  459. dedge_t *in;
  460. medge_t *out;
  461. int i, count;
  462. in = (void *)(mod_base + l->fileofs);
  463. if (l->filelen % sizeof(*in))
  464. SV_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
  465. count = l->filelen / sizeof(*in);
  466. out = Hunk_AllocName ( (count + 1) * sizeof(*out), loadname);
  467. loadmodel->edges = out;
  468. loadmodel->numedges = count;
  469. for ( i=0 ; i<count ; i++, in++, out++)
  470. {
  471. out->v[0] = (unsigned short)LittleShort(in->v[0]);
  472. out->v[1] = (unsigned short)LittleShort(in->v[1]);
  473. }
  474. }
  475. /*
  476. =================
  477. Mod_LoadTexinfo
  478. =================
  479. */
  480. void Mod_LoadTexinfo (lump_t *l)
  481. {
  482. texinfo_t *in;
  483. mtexinfo_t *out;
  484. int i, j, count;
  485. int miptex;
  486. float len1, len2;
  487. in = (void *)(mod_base + l->fileofs);
  488. if (l->filelen % sizeof(*in))
  489. SV_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
  490. count = l->filelen / sizeof(*in);
  491. out = Hunk_AllocName ( count*sizeof(*out), loadname);
  492. loadmodel->texinfo = out;
  493. loadmodel->numtexinfo = count;
  494. for ( i=0 ; i<count ; i++, in++, out++)
  495. {
  496. #if 0
  497. for (j=0 ; j<8 ; j++)
  498. out->vecs[0][j] = LittleFloat (in->vecs[0][j]);
  499. len1 = Length (in->vecs[0]);
  500. len2 = Length (in->vecs[1]);
  501. #else
  502. for (j=0 ; j<4 ; j++) {
  503. out->vecs[0][j] = LittleFloat (in->vecs[0][j]);
  504. out->vecs[1][j] = LittleFloat (in->vecs[1][j]);
  505. }
  506. len1 = Length (out->vecs[0]);
  507. len2 = Length (out->vecs[1]);
  508. #endif
  509. if (len1 + len2 < 2 /*0.001*/)
  510. out->mipadjust = 1;
  511. else
  512. out->mipadjust = 1 / floor( (len1+len2)/2 );
  513. miptex = LittleLong (in->miptex);
  514. out->flags = LittleLong (in->flags);
  515. if (!loadmodel->textures)
  516. {
  517. out->texture = &r_notexture_mip; // checkerboard texture
  518. out->flags = 0;
  519. }
  520. else
  521. {
  522. if (miptex >= loadmodel->numtextures)
  523. SV_Error ("miptex >= loadmodel->numtextures");
  524. out->texture = loadmodel->textures[miptex];
  525. if (!out->texture)
  526. {
  527. out->texture = &r_notexture_mip; // texture not found
  528. out->flags = 0;
  529. }
  530. }
  531. }
  532. }
  533. /*
  534. ================
  535. CalcSurfaceExtents
  536. Fills in s->texturemins[] and s->extents[]
  537. ================
  538. */
  539. void CalcSurfaceExtents (msurface_t *s)
  540. {
  541. float mins[2], maxs[2], val;
  542. int i,j, e;
  543. mvertex_t *v;
  544. mtexinfo_t *tex;
  545. int bmins[2], bmaxs[2];
  546. mins[0] = mins[1] = 999999;
  547. maxs[0] = maxs[1] = -99999;
  548. tex = s->texinfo;
  549. for (i=0 ; i<s->numedges ; i++)
  550. {
  551. e = loadmodel->surfedges[s->firstedge+i];
  552. if (e >= 0)
  553. v = &loadmodel->vertexes[loadmodel->edges[e].v[0]];
  554. else
  555. v = &loadmodel->vertexes[loadmodel->edges[-e].v[1]];
  556. for (j=0 ; j<2 ; j++)
  557. {
  558. val = v->position[0] * tex->vecs[j][0] +
  559. v->position[1] * tex->vecs[j][1] +
  560. v->position[2] * tex->vecs[j][2] +
  561. tex->vecs[j][3];
  562. if (val < mins[j])
  563. mins[j] = val;
  564. if (val > maxs[j])
  565. maxs[j] = val;
  566. }
  567. }
  568. for (i=0 ; i<2 ; i++)
  569. {
  570. bmins[i] = floor(mins[i]/16);
  571. bmaxs[i] = ceil(maxs[i]/16);
  572. s->texturemins[i] = bmins[i] * 16;
  573. s->extents[i] = (bmaxs[i] - bmins[i]) * 16;
  574. if ( !(tex->flags & TEX_SPECIAL) && s->extents[i] > 256)
  575. SV_Error ("Bad surface extents");
  576. }
  577. }
  578. /*
  579. =================
  580. Mod_LoadFaces
  581. =================
  582. */
  583. void Mod_LoadFaces (lump_t *l)
  584. {
  585. dface_t *in;
  586. msurface_t *out;
  587. int i, count, surfnum;
  588. int planenum, side;
  589. in = (void *)(mod_base + l->fileofs);
  590. if (l->filelen % sizeof(*in))
  591. SV_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
  592. count = l->filelen / sizeof(*in);
  593. out = Hunk_AllocName ( count*sizeof(*out), loadname);
  594. loadmodel->surfaces = out;
  595. loadmodel->numsurfaces = count;
  596. for ( surfnum=0 ; surfnum<count ; surfnum++, in++, out++)
  597. {
  598. out->firstedge = LittleLong(in->firstedge);
  599. out->numedges = LittleShort(in->numedges);
  600. out->flags = 0;
  601. planenum = LittleShort(in->planenum);
  602. side = LittleShort(in->side);
  603. if (side)
  604. out->flags |= SURF_PLANEBACK;
  605. out->plane = loadmodel->planes + planenum;
  606. out->texinfo = loadmodel->texinfo + LittleShort (in->texinfo);
  607. CalcSurfaceExtents (out);
  608. // lighting info
  609. for (i=0 ; i<MAXLIGHTMAPS ; i++)
  610. out->styles[i] = in->styles[i];
  611. i = LittleLong(in->lightofs);
  612. if (i == -1)
  613. out->samples = NULL;
  614. else
  615. out->samples = loadmodel->lightdata + i;
  616. // set the drawing flags flag
  617. if (!Q_strncmp(out->texinfo->texture->name,"sky",3)) // sky
  618. {
  619. out->flags |= (SURF_DRAWSKY | SURF_DRAWTILED);
  620. continue;
  621. }
  622. if (!Q_strncmp(out->texinfo->texture->name,"*",1)) // turbulent
  623. {
  624. out->flags |= (SURF_DRAWTURB | SURF_DRAWTILED);
  625. for (i=0 ; i<2 ; i++)
  626. {
  627. out->extents[i] = 16384;
  628. out->texturemins[i] = -8192;
  629. }
  630. continue;
  631. }
  632. }
  633. }
  634. /*
  635. =================
  636. Mod_SetParent
  637. =================
  638. */
  639. void Mod_SetParent (mnode_t *node, mnode_t *parent)
  640. {
  641. node->parent = parent;
  642. if (node->contents < 0)
  643. return;
  644. Mod_SetParent (node->children[0], node);
  645. Mod_SetParent (node->children[1], node);
  646. }
  647. /*
  648. =================
  649. Mod_LoadNodes
  650. =================
  651. */
  652. void Mod_LoadNodes (lump_t *l)
  653. {
  654. int i, j, count, p;
  655. dnode_t *in;
  656. mnode_t *out;
  657. in = (void *)(mod_base + l->fileofs);
  658. if (l->filelen % sizeof(*in))
  659. SV_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
  660. count = l->filelen / sizeof(*in);
  661. out = Hunk_AllocName ( count*sizeof(*out), loadname);
  662. loadmodel->nodes = out;
  663. loadmodel->numnodes = count;
  664. for ( i=0 ; i<count ; i++, in++, out++)
  665. {
  666. for (j=0 ; j<3 ; j++)
  667. {
  668. out->minmaxs[j] = LittleShort (in->mins[j]);
  669. out->minmaxs[3+j] = LittleShort (in->maxs[j]);
  670. }
  671. p = LittleLong(in->planenum);
  672. out->plane = loadmodel->planes + p;
  673. out->firstsurface = LittleShort (in->firstface);
  674. out->numsurfaces = LittleShort (in->numfaces);
  675. for (j=0 ; j<2 ; j++)
  676. {
  677. p = LittleShort (in->children[j]);
  678. if (p >= 0)
  679. out->children[j] = loadmodel->nodes + p;
  680. else
  681. out->children[j] = (mnode_t *)(loadmodel->leafs + (-1 - p));
  682. }
  683. }
  684. Mod_SetParent (loadmodel->nodes, NULL); // sets nodes and leafs
  685. }
  686. /*
  687. =================
  688. Mod_LoadLeafs
  689. =================
  690. */
  691. void Mod_LoadLeafs (lump_t *l)
  692. {
  693. dleaf_t *in;
  694. mleaf_t *out;
  695. int i, j, count, p;
  696. in = (void *)(mod_base + l->fileofs);
  697. if (l->filelen % sizeof(*in))
  698. SV_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
  699. count = l->filelen / sizeof(*in);
  700. out = Hunk_AllocName ( count*sizeof(*out), loadname);
  701. loadmodel->leafs = out;
  702. loadmodel->numleafs = count;
  703. for ( i=0 ; i<count ; i++, in++, out++)
  704. {
  705. for (j=0 ; j<3 ; j++)
  706. {
  707. out->minmaxs[j] = LittleShort (in->mins[j]);
  708. out->minmaxs[3+j] = LittleShort (in->maxs[j]);
  709. }
  710. p = LittleLong(in->contents);
  711. out->contents = p;
  712. out->firstmarksurface = loadmodel->marksurfaces +
  713. LittleShort(in->firstmarksurface);
  714. out->nummarksurfaces = LittleShort(in->nummarksurfaces);
  715. p = LittleLong(in->visofs);
  716. if (p == -1)
  717. out->compressed_vis = NULL;
  718. else
  719. out->compressed_vis = loadmodel->visdata + p;
  720. out->efrags = NULL;
  721. for (j=0 ; j<4 ; j++)
  722. out->ambient_sound_level[j] = in->ambient_level[j];
  723. }
  724. }
  725. /*
  726. =================
  727. Mod_LoadClipnodes
  728. =================
  729. */
  730. void Mod_LoadClipnodes (lump_t *l)
  731. {
  732. dclipnode_t *in, *out;
  733. int i, count;
  734. hull_t *hull;
  735. in = (void *)(mod_base + l->fileofs);
  736. if (l->filelen % sizeof(*in))
  737. SV_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
  738. count = l->filelen / sizeof(*in);
  739. out = Hunk_AllocName ( count*sizeof(*out), loadname);
  740. loadmodel->clipnodes = out;
  741. loadmodel->numclipnodes = count;
  742. hull = &loadmodel->hulls[1];
  743. hull->clipnodes = out;
  744. hull->firstclipnode = 0;
  745. hull->lastclipnode = count-1;
  746. hull->planes = loadmodel->planes;
  747. hull->clip_mins[0] = -16;
  748. hull->clip_mins[1] = -16;
  749. hull->clip_mins[2] = -24;
  750. hull->clip_maxs[0] = 16;
  751. hull->clip_maxs[1] = 16;
  752. hull->clip_maxs[2] = 32;
  753. hull = &loadmodel->hulls[2];
  754. hull->clipnodes = out;
  755. hull->firstclipnode = 0;
  756. hull->lastclipnode = count-1;
  757. hull->planes = loadmodel->planes;
  758. hull->clip_mins[0] = -32;
  759. hull->clip_mins[1] = -32;
  760. hull->clip_mins[2] = -24;
  761. hull->clip_maxs[0] = 32;
  762. hull->clip_maxs[1] = 32;
  763. hull->clip_maxs[2] = 64;
  764. for (i=0 ; i<count ; i++, out++, in++)
  765. {
  766. out->planenum = LittleLong(in->planenum);
  767. out->children[0] = LittleShort(in->children[0]);
  768. out->children[1] = LittleShort(in->children[1]);
  769. }
  770. }
  771. /*
  772. =================
  773. Mod_MakeHull0
  774. Deplicate the drawing hull structure as a clipping hull
  775. =================
  776. */
  777. void Mod_MakeHull0 (void)
  778. {
  779. mnode_t *in, *child;
  780. dclipnode_t *out;
  781. int i, j, count;
  782. hull_t *hull;
  783. hull = &loadmodel->hulls[0];
  784. in = loadmodel->nodes;
  785. count = loadmodel->numnodes;
  786. out = Hunk_AllocName ( count*sizeof(*out), loadname);
  787. hull->clipnodes = out;
  788. hull->firstclipnode = 0;
  789. hull->lastclipnode = count-1;
  790. hull->planes = loadmodel->planes;
  791. for (i=0 ; i<count ; i++, out++, in++)
  792. {
  793. out->planenum = in->plane - loadmodel->planes;
  794. for (j=0 ; j<2 ; j++)
  795. {
  796. child = in->children[j];
  797. if (child->contents < 0)
  798. out->children[j] = child->contents;
  799. else
  800. out->children[j] = child - loadmodel->nodes;
  801. }
  802. }
  803. }
  804. /*
  805. =================
  806. Mod_LoadMarksurfaces
  807. =================
  808. */
  809. void Mod_LoadMarksurfaces (lump_t *l)
  810. {
  811. int i, j, count;
  812. short *in;
  813. msurface_t **out;
  814. in = (void *)(mod_base + l->fileofs);
  815. if (l->filelen % sizeof(*in))
  816. SV_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
  817. count = l->filelen / sizeof(*in);
  818. out = Hunk_AllocName ( count*sizeof(*out), loadname);
  819. loadmodel->marksurfaces = out;
  820. loadmodel->nummarksurfaces = count;
  821. for ( i=0 ; i<count ; i++)
  822. {
  823. j = LittleShort(in[i]);
  824. if (j >= loadmodel->numsurfaces)
  825. SV_Error ("Mod_ParseMarksurfaces: bad surface number");
  826. out[i] = loadmodel->surfaces + j;
  827. }
  828. }
  829. /*
  830. =================
  831. Mod_LoadSurfedges
  832. =================
  833. */
  834. void Mod_LoadSurfedges (lump_t *l)
  835. {
  836. int i, count;
  837. int *in, *out;
  838. in = (void *)(mod_base + l->fileofs);
  839. if (l->filelen % sizeof(*in))
  840. SV_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
  841. count = l->filelen / sizeof(*in);
  842. out = Hunk_AllocName ( count*sizeof(*out), loadname);
  843. loadmodel->surfedges = out;
  844. loadmodel->numsurfedges = count;
  845. for ( i=0 ; i<count ; i++)
  846. out[i] = LittleLong (in[i]);
  847. }
  848. /*
  849. =================
  850. Mod_LoadPlanes
  851. =================
  852. */
  853. void Mod_LoadPlanes (lump_t *l)
  854. {
  855. int i, j;
  856. mplane_t *out;
  857. dplane_t *in;
  858. int count;
  859. int bits;
  860. in = (void *)(mod_base + l->fileofs);
  861. if (l->filelen % sizeof(*in))
  862. SV_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
  863. count = l->filelen / sizeof(*in);
  864. out = Hunk_AllocName ( count*2*sizeof(*out), loadname);
  865. loadmodel->planes = out;
  866. loadmodel->numplanes = count;
  867. for ( i=0 ; i<count ; i++, in++, out++)
  868. {
  869. bits = 0;
  870. for (j=0 ; j<3 ; j++)
  871. {
  872. out->normal[j] = LittleFloat (in->normal[j]);
  873. if (out->normal[j] < 0)
  874. bits |= 1<<j;
  875. }
  876. out->dist = LittleFloat (in->dist);
  877. out->type = LittleLong (in->type);
  878. out->signbits = bits;
  879. }
  880. }
  881. /*
  882. =================
  883. Mod_LoadBrushModel
  884. =================
  885. */
  886. void Mod_LoadBrushModel (model_t *mod, void *buffer)
  887. {
  888. int i, j;
  889. dheader_t *header;
  890. dmodel_t *bm;
  891. loadmodel->type = mod_brush;
  892. header = (dheader_t *)buffer;
  893. i = LittleLong (header->version);
  894. if (i != BSPVERSION)
  895. SV_Error ("Mod_LoadBrushModel: %s has wrong version number (%i should be %i)", mod->name, i, BSPVERSION);
  896. // swap all the lumps
  897. mod_base = (byte *)header;
  898. for (i=0 ; i<sizeof(dheader_t)/4 ; i++)
  899. ((int *)header)[i] = LittleLong ( ((int *)header)[i]);
  900. // load into heap
  901. mod->checksum = 0;
  902. mod->checksum2 = 0;
  903. // checksum all of the map, except for entities
  904. for (i = 0; i < HEADER_LUMPS; i++) {
  905. if (i == LUMP_ENTITIES)
  906. continue;
  907. mod->checksum ^= LittleLong(Com_BlockChecksum(mod_base + header->lumps[i].fileofs,
  908. header->lumps[i].filelen));
  909. if (i == LUMP_VISIBILITY || i == LUMP_LEAFS || i == LUMP_NODES)
  910. continue;
  911. mod->checksum2 ^= LittleLong(Com_BlockChecksum(mod_base + header->lumps[i].fileofs,
  912. header->lumps[i].filelen));
  913. }
  914. Mod_LoadVertexes (&header->lumps[LUMP_VERTEXES]);
  915. Mod_LoadEdges (&header->lumps[LUMP_EDGES]);
  916. Mod_LoadSurfedges (&header->lumps[LUMP_SURFEDGES]);
  917. Mod_LoadTextures (&header->lumps[LUMP_TEXTURES]);
  918. Mod_LoadLighting (&header->lumps[LUMP_LIGHTING]);
  919. Mod_LoadPlanes (&header->lumps[LUMP_PLANES]);
  920. Mod_LoadTexinfo (&header->lumps[LUMP_TEXINFO]);
  921. Mod_LoadFaces (&header->lumps[LUMP_FACES]);
  922. Mod_LoadMarksurfaces (&header->lumps[LUMP_MARKSURFACES]);
  923. Mod_LoadVisibility (&header->lumps[LUMP_VISIBILITY]);
  924. Mod_LoadLeafs (&header->lumps[LUMP_LEAFS]);
  925. Mod_LoadNodes (&header->lumps[LUMP_NODES]);
  926. Mod_LoadClipnodes (&header->lumps[LUMP_CLIPNODES]);
  927. Mod_LoadEntities (&header->lumps[LUMP_ENTITIES]);
  928. Mod_LoadSubmodels (&header->lumps[LUMP_MODELS]);
  929. Mod_MakeHull0 ();
  930. mod->numframes = 2; // regular and alternate animation
  931. //
  932. // set up the submodels (FIXME: this is confusing)
  933. //
  934. for (i=0 ; i<mod->numsubmodels ; i++)
  935. {
  936. bm = &mod->submodels[i];
  937. mod->hulls[0].firstclipnode = bm->headnode[0];
  938. for (j=1 ; j<MAX_MAP_HULLS ; j++)
  939. {
  940. mod->hulls[j].firstclipnode = bm->headnode[j];
  941. mod->hulls[j].lastclipnode = mod->numclipnodes-1;
  942. }
  943. mod->firstmodelsurface = bm->firstface;
  944. mod->nummodelsurfaces = bm->numfaces;
  945. VectorCopy (bm->maxs, mod->maxs);
  946. VectorCopy (bm->mins, mod->mins);
  947. mod->numleafs = bm->visleafs;
  948. if (i < mod->numsubmodels-1)
  949. { // duplicate the basic information
  950. char name[10];
  951. sprintf (name, "*%i", i+1);
  952. loadmodel = Mod_FindName (name);
  953. *loadmodel = *mod;
  954. strcpy (loadmodel->name, name);
  955. mod = loadmodel;
  956. }
  957. }
  958. }