cm_load_xbox.cpp 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281
  1. // cmodel.c -- model loading
  2. #include "cm_local.h"
  3. #include "cm_patch.h"
  4. #include "../renderer/tr_local.h"
  5. #include "../RMG/RM_Headers.h"
  6. #include "sparc.h"
  7. #include "../zlib/zlib.h"
  8. static SPARC<byte> visData;
  9. void *SparcAllocator(unsigned int size)
  10. {
  11. return Z_Malloc(size, TAG_BSP, false);
  12. }
  13. void SparcDeallocator(void *ptr)
  14. {
  15. Z_Free(ptr);
  16. }
  17. extern world_t s_worldData;
  18. void CM_LoadShaderText(bool forceReload);
  19. #ifdef BSPC
  20. void SetPlaneSignbits (cplane_t *out) {
  21. int bits, j;
  22. // for fast box on planeside test
  23. bits = 0;
  24. for (j=0 ; j<3 ; j++) {
  25. if (out->normal[j] < 0) {
  26. bits |= 1<<j;
  27. }
  28. }
  29. out->signbits = bits;
  30. }
  31. #endif //BSPC
  32. // to allow boxes to be treated as brush models, we allocate
  33. // some extra indexes along with those needed by the map
  34. #define BOX_BRUSHES 1
  35. #define BOX_SIDES 6
  36. #define BOX_LEAFS 2
  37. #define BOX_PLANES 12
  38. #define LL(x) x=LittleLong(x)
  39. clipMap_t cmg;
  40. int c_pointcontents;
  41. int c_traces, c_brush_traces, c_patch_traces;
  42. byte *cmod_base;
  43. #ifndef BSPC
  44. cvar_t *cm_noAreas;
  45. cvar_t *cm_noCurves;
  46. cvar_t *cm_playerCurveClip;
  47. #endif
  48. cmodel_t box_model;
  49. cplane_t *box_planes;
  50. cbrush_t *box_brush;
  51. int CM_OrOfAllContentsFlagsInMap;
  52. void CM_InitBoxHull (void);
  53. void CM_FloodAreaConnections (void);
  54. clipMap_t SubBSP[MAX_SUB_BSP];
  55. int NumSubBSP = 0, TotalSubModels = 0;
  56. /*
  57. ===============================================================================
  58. MAP LOADING
  59. ===============================================================================
  60. */
  61. /*
  62. =================
  63. CMod_LoadShaders
  64. =================
  65. */
  66. void CMod_LoadShaders( void *data, int len ) {
  67. dshader_t *in;
  68. int i, count;
  69. CCMShader *out;
  70. in = (dshader_t *)(data);
  71. if (len % sizeof(*in)) {
  72. Com_Error (ERR_DROP, "CMod_LoadShaders: funny lump size");
  73. }
  74. count = len / sizeof(*in);
  75. if (count < 1) {
  76. Com_Error (ERR_DROP, "Map with no shaders");
  77. }
  78. cmg.shaders = (CCMShader *) Z_Malloc( count * sizeof( *cmg.shaders ), TAG_BSP, qfalse);
  79. cmg.numShaders = count;
  80. s_worldData.shaders = (dshader_t *) Z_Malloc ( count*sizeof(dshader_t), TAG_BSP, qfalse );
  81. s_worldData.numShaders = count;
  82. out = cmg.shaders;
  83. for ( i = 0; i < count; i++, in++, out++ )
  84. {
  85. Q_strncpyz(out->shader, in->shader, MAX_QPATH);
  86. out->contentFlags = in->contentFlags;
  87. out->surfaceFlags = in->surfaceFlags;
  88. Q_strncpyz(s_worldData.shaders[i].shader, in->shader, MAX_QPATH);
  89. s_worldData.shaders[i].contentFlags = in->contentFlags;
  90. s_worldData.shaders[i].surfaceFlags = in->surfaceFlags;
  91. }
  92. }
  93. /*
  94. =================
  95. CMod_LoadSubmodels
  96. =================
  97. */
  98. void CMod_LoadSubmodels( void *data, int len ) {
  99. dmodel_t *in;
  100. cmodel_t *out;
  101. int i, j, count;
  102. int *indexes;
  103. in = (dmodel_t *)(data);
  104. if (len % sizeof(*in))
  105. Com_Error (ERR_DROP, "CMod_LoadSubmodels: funny lump size");
  106. count = len / sizeof(*in);
  107. if (count < 1) {
  108. Com_Error (ERR_DROP, "Map with no models");
  109. }
  110. if ( count > MAX_SUBMODELS ) {
  111. Com_Error( ERR_DROP, "MAX_SUBMODELS (%d) exceeded by %d", MAX_SUBMODELS, count-MAX_SUBMODELS );
  112. }
  113. cmg.cmodels = (struct cmodel_s *) Z_Malloc( count * sizeof( *cmg.cmodels ), TAG_BSP, qtrue );
  114. cmg.numSubModels = count;
  115. for ( i=0 ; i<count ; i++, in++, out++)
  116. {
  117. out = &cmg.cmodels[i];
  118. for (j=0 ; j<3 ; j++)
  119. { // spread the mins / maxs by a pixel
  120. out->mins[j] = in->mins[j] - 1;
  121. out->maxs[j] = in->maxs[j] + 1;
  122. }
  123. if ( i == 0 ) {
  124. continue; // world model doesn't need other info
  125. }
  126. // make a "leaf" just to hold the model's brushes and surfaces
  127. out->leaf.numLeafBrushes = in->numBrushes;
  128. indexes = (int *) Z_Malloc( out->leaf.numLeafBrushes * 4, TAG_BSP, qfalse);
  129. out->leaf.firstLeafBrush = indexes - cmg.leafbrushes;
  130. for ( j = 0 ; j < out->leaf.numLeafBrushes ; j++ ) {
  131. indexes[j] = in->firstBrush + j;
  132. }
  133. out->leaf.numLeafSurfaces = in->numSurfaces;
  134. indexes = (int *) Z_Malloc( out->leaf.numLeafSurfaces * 4, TAG_BSP, qfalse);
  135. out->leaf.firstLeafSurface = indexes - cmg.leafsurfaces;
  136. for ( j = 0 ; j < out->leaf.numLeafSurfaces ; j++ ) {
  137. indexes[j] = in->firstSurface + j;
  138. }
  139. }
  140. }
  141. /*
  142. =================
  143. CMod_LoadNodes
  144. =================
  145. */
  146. void CMod_LoadNodes( void *data, int len ) {
  147. dnode_t *in;
  148. cNode_t *out;
  149. int i, count;
  150. in = (dnode_t *)(data);
  151. if (len % sizeof(*in))
  152. Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size");
  153. count = len / sizeof(*in);
  154. if (count < 1)
  155. Com_Error (ERR_DROP, "Map has no nodes");
  156. cmg.nodes = (cNode_t *) Z_Malloc( count * sizeof( *cmg.nodes ), TAG_BSP, qfalse);
  157. cmg.numNodes = count;
  158. out = cmg.nodes;
  159. for (i=0 ; i<count ; i++, out++, in++)
  160. {
  161. out->children[0] = in->children[0];
  162. out->children[1] = in->children[1];
  163. }
  164. }
  165. /*
  166. =================
  167. CM_BoundBrush
  168. =================
  169. */
  170. void CM_BoundBrush( cbrush_t *b ) {
  171. b->bounds[0][0] = -cmg.planes[b->sides[0].planeNum.GetValue()].dist;
  172. b->bounds[1][0] = cmg.planes[b->sides[1].planeNum.GetValue()].dist;
  173. b->bounds[0][1] = -cmg.planes[b->sides[2].planeNum.GetValue()].dist;
  174. b->bounds[1][1] = cmg.planes[b->sides[3].planeNum.GetValue()].dist;
  175. b->bounds[0][2] = -cmg.planes[b->sides[4].planeNum.GetValue()].dist;
  176. b->bounds[1][2] = cmg.planes[b->sides[5].planeNum.GetValue()].dist;
  177. }
  178. /*
  179. =================
  180. CMod_LoadBrushes
  181. =================
  182. */
  183. void CMod_LoadBrushes( void *data, int len ) {
  184. dbrush_t *in;
  185. cbrush_t *out;
  186. int i, count;
  187. in = (dbrush_t *)(data);
  188. if (len % sizeof(*in)) {
  189. Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size");
  190. }
  191. count = len / sizeof(*in);
  192. cmg.brushes = (cbrush_t *) Z_Malloc( ( BOX_BRUSHES + count ) * sizeof( *cmg.brushes ), TAG_BSP, qfalse);
  193. cmg.numBrushes = count;
  194. out = cmg.brushes;
  195. for ( i=0 ; i<count ; i++, out++, in++ ) {
  196. out->sides = cmg.brushsides + in->firstSide;
  197. out->numsides = in->numSides;
  198. out->shaderNum = in->shaderNum;
  199. if ( out->shaderNum < 0 || out->shaderNum >= cmg.numShaders ) {
  200. Com_Error( ERR_DROP, "CMod_LoadBrushes: bad shaderNum: %i", out->shaderNum );
  201. }
  202. out->contents = cmg.shaders[out->shaderNum].contentFlags;
  203. //TEMP HACK: for water that cuts vis but is not solid!!!
  204. if ( cmg.shaders[out->shaderNum].surfaceFlags & SURF_SLICK )
  205. {
  206. out->contents &= ~CONTENTS_SOLID;
  207. }
  208. CM_OrOfAllContentsFlagsInMap |= out->contents;
  209. CM_BoundBrush( out );
  210. }
  211. }
  212. /*
  213. =================
  214. CMod_LoadLeafs
  215. =================
  216. */
  217. void CMod_LoadLeafs (void *data, int len)
  218. {
  219. int i;
  220. cLeaf_t *out;
  221. dleaf_t *in;
  222. int count;
  223. in = (dleaf_t *)(data);
  224. if (len % sizeof(*in))
  225. Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size");
  226. count = len / sizeof(*in);
  227. if (count < 1)
  228. Com_Error (ERR_DROP, "Map with no leafs");
  229. cmg.leafs = (cLeaf_t *) Z_Malloc( ( BOX_LEAFS + count ) * sizeof( *cmg.leafs ), TAG_BSP, qfalse);
  230. cmg.numLeafs = count;
  231. out = cmg.leafs;
  232. for ( i=0 ; i<count ; i++, in++, out++)
  233. {
  234. out->cluster = in->cluster;
  235. out->area = in->area;
  236. out->firstLeafBrush = in->firstLeafBrush;
  237. out->numLeafBrushes = in->numLeafBrushes;
  238. out->firstLeafSurface = in->firstLeafSurface;
  239. out->numLeafSurfaces = in->numLeafSurfaces;
  240. if (out->cluster >= cmg.numClusters)
  241. cmg.numClusters = out->cluster + 1;
  242. if (out->area >= cmg.numAreas)
  243. cmg.numAreas = out->area + 1;
  244. }
  245. cmg.areas = (cArea_t *) Z_Malloc( cmg.numAreas * sizeof( *cmg.areas ), TAG_BSP, qtrue );
  246. extern qboolean vidRestartReloadMap;
  247. if (!vidRestartReloadMap)
  248. {
  249. cmg.areaPortals = (int *) Z_Malloc( cmg.numAreas * cmg.numAreas * sizeof( *cmg.areaPortals ), TAG_BSP, qtrue );
  250. }
  251. }
  252. /*
  253. =================
  254. CMod_LoadPlanes
  255. =================
  256. */
  257. void CMod_LoadPlanes (void *data, int len)
  258. {
  259. int i, j;
  260. cplane_t *out;
  261. dplane_t *in;
  262. int count;
  263. int bits;
  264. in = (dplane_t *)(data);
  265. if (len % sizeof(*in))
  266. Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size");
  267. count = len / sizeof(*in);
  268. if (count < 1)
  269. Com_Error (ERR_DROP, "Map with no planes");
  270. cmg.planes = (struct cplane_s *) Z_Malloc( ( BOX_PLANES + count ) * sizeof( *cmg.planes ), TAG_BSP, qfalse);
  271. cmg.numPlanes = count;
  272. out = cmg.planes;
  273. for ( i=0 ; i<count ; i++, in++, out++)
  274. {
  275. bits = 0;
  276. for (j=0 ; j<3 ; j++)
  277. {
  278. out->normal[j] = in->normal[j];
  279. if (out->normal[j] < 0)
  280. bits |= 1<<j;
  281. }
  282. out->dist = in->dist;
  283. out->type = PlaneTypeForNormal( out->normal );
  284. out->signbits = bits;
  285. }
  286. }
  287. /*
  288. =================
  289. CMod_LoadLeafBrushes
  290. =================
  291. */
  292. void CMod_LoadLeafBrushes (void *data, int len)
  293. {
  294. int *out;
  295. int *in;
  296. int count;
  297. in = (int *)(data);
  298. if (len % sizeof(*in))
  299. Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size");
  300. count = len / sizeof(*in);
  301. cmg.leafbrushes = (int *) Z_Malloc( ( BOX_BRUSHES + count ) * sizeof( *cmg.leafbrushes ), TAG_BSP, qfalse);
  302. cmg.numLeafBrushes = count;
  303. out = cmg.leafbrushes;
  304. memcpy(out, in, len);
  305. }
  306. /*
  307. =================
  308. CMod_LoadBrushSides
  309. =================
  310. */
  311. void CMod_LoadBrushSides (void *data, int len)
  312. {
  313. int i;
  314. cbrushside_t *out;
  315. dbrushside_t *in;
  316. int count;
  317. in = (dbrushside_t *)(data);
  318. if ( len % sizeof(*in) ) {
  319. Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size");
  320. }
  321. count = len / sizeof(*in);
  322. cmg.brushsides = (cbrushside_t *) Z_Malloc( ( BOX_SIDES + count ) * sizeof( *cmg.brushsides ), TAG_BSP, qfalse);
  323. cmg.numBrushSides = count;
  324. out = cmg.brushsides;
  325. for ( i=0 ; i<count ; i++, in++, out++) {
  326. out->planeNum = in->planeNum;
  327. assert(in->planeNum == out->planeNum.GetValue());
  328. out->shaderNum = in->shaderNum;
  329. if ( out->shaderNum < 0 || out->shaderNum >= cmg.numShaders ) {
  330. Com_Error( ERR_DROP, "CMod_LoadBrushSides: bad shaderNum: %i", out->shaderNum );
  331. }
  332. }
  333. }
  334. /*
  335. =================
  336. CMod_LoadEntityString
  337. =================
  338. */
  339. void CMod_LoadEntityString( void *data, int len ) {
  340. cmg.entityString = (char *) Z_Malloc( len, TAG_BSP, qfalse);
  341. cmg.numEntityChars = len;
  342. memcpy (cmg.entityString, data, len);
  343. }
  344. /*
  345. =================
  346. CMod_LoadVisibility
  347. =================
  348. */
  349. #define VIS_HEADER 8
  350. void CMod_LoadVisibility( void *data, int len ) {
  351. char *buf;
  352. if ( !len ) {
  353. cmg.visibility = NULL;
  354. return;
  355. }
  356. buf = (char*)data;
  357. visData.SetAllocator(SparcAllocator, SparcDeallocator);
  358. cmg.vised = qtrue;
  359. cmg.numClusters = ((int *)buf)[0];
  360. cmg.clusterBytes = ((int *)buf)[1];
  361. visData.Load(buf + VIS_HEADER, len - VIS_HEADER);
  362. cmg.visibility = &visData;
  363. RE_SetWorldVisData(&visData);
  364. }
  365. //==================================================================
  366. /*
  367. =================
  368. CMod_LoadPatches
  369. =================
  370. */
  371. #define MAX_PATCH_VERTS 1024
  372. void CMod_LoadPatches( void *verts, int vertlen, void *surfaces, int surfacelen, int numsurfs ) {
  373. mapVert_t *dv, *dv_p;
  374. dpatch_t *in;
  375. int count;
  376. int i, j;
  377. int c;
  378. cPatch_t *patch;
  379. vec3_t points[MAX_PATCH_VERTS];
  380. int width, height;
  381. int shaderNum;
  382. count = surfacelen / sizeof(*in);
  383. cmg.numSurfaces = numsurfs;
  384. cmg.surfaces = (cPatch_t **) Z_Malloc( cmg.numSurfaces * sizeof( cmg.surfaces[0] ), TAG_BSP, qtrue );
  385. dv = (mapVert_t *)(verts);
  386. if (vertlen % sizeof(*dv))
  387. Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size");
  388. unsigned char* patchScratch = (unsigned char*)Z_Malloc( sizeof( *patch ) * count, TAG_BSP, qtrue);
  389. extern void CM_GridAlloc();
  390. extern void CM_PatchCollideFromGridTempAlloc();
  391. extern void CM_PreparePatchCollide(int num);
  392. extern void CM_TempPatchPlanesAlloc();
  393. CM_GridAlloc();
  394. CM_PatchCollideFromGridTempAlloc();
  395. CM_PreparePatchCollide(count);
  396. CM_TempPatchPlanesAlloc();
  397. facetLoad_t *facetbuf = (facetLoad_t*)Z_Malloc(
  398. MAX_PATCH_PLANES*sizeof(facetLoad_t), TAG_TEMP_WORKSPACE, qfalse);
  399. int *gridbuf = (int*)Z_Malloc(
  400. CM_MAX_GRID_SIZE*CM_MAX_GRID_SIZE*2*sizeof(int), TAG_TEMP_WORKSPACE, qfalse);
  401. for ( i = 0 ; i < count ; i++) {
  402. in = (dpatch_t *)surfaces + i;
  403. cmg.surfaces[ in->code ] = patch = (cPatch_t *) patchScratch;
  404. patchScratch += sizeof( *patch );
  405. // load the full drawverts onto the stack
  406. width = in->patchWidth;
  407. height = in->patchHeight;
  408. c = width * height;
  409. if ( c > MAX_PATCH_VERTS ) {
  410. Com_Error( ERR_DROP, "ParseMesh: MAX_PATCH_VERTS" );
  411. }
  412. dv_p = dv + (in->verts >> 12);
  413. for ( j = 0 ; j < c ; j++, dv_p++ ) {
  414. points[j][0] = dv_p->xyz[0];
  415. points[j][1] = dv_p->xyz[1];
  416. points[j][2] = dv_p->xyz[2];
  417. }
  418. shaderNum = in->shaderNum;
  419. patch->contents = cmg.shaders[shaderNum].contentFlags;
  420. CM_OrOfAllContentsFlagsInMap |= patch->contents;
  421. patch->surfaceFlags = cmg.shaders[shaderNum].surfaceFlags;
  422. // create the internal facet structure
  423. patch->pc = CM_GeneratePatchCollide( width, height, points, facetbuf, gridbuf );
  424. }
  425. extern void CM_GridDealloc();
  426. extern void CM_PatchCollideFromGridTempDealloc();
  427. extern void CM_TempPatchPlanesDealloc();
  428. CM_PatchCollideFromGridTempDealloc();
  429. CM_GridDealloc();
  430. CM_TempPatchPlanesDealloc();
  431. Z_Free(gridbuf);
  432. Z_Free(facetbuf);
  433. }
  434. //==================================================================
  435. #ifdef BSPC
  436. /*
  437. ==================
  438. CM_FreeMap
  439. Free any loaded map and all submodels
  440. ==================
  441. */
  442. void CM_FreeMap(void) {
  443. memset( &cmg, 0, sizeof( cmg ) );
  444. Hunk_ClearHigh();
  445. CM_ClearLevelPatches();
  446. }
  447. #endif //BSPC
  448. /*
  449. ==================
  450. CM_LoadMap
  451. Loads in the map and all submodels
  452. ==================
  453. */
  454. void *gpvCachedMapDiskImage = NULL;
  455. char gsCachedMapDiskImage[MAX_QPATH];
  456. qboolean gbUsingCachedMapDataRightNow = qfalse; // if true, signifies that you can't delete this at the moment!! (used during z_malloc()-fail recovery attempt)
  457. // called in response to a "devmapbsp blah" or "devmapall blah" command, do NOT use inside CM_Load unless you pass in qtrue
  458. //
  459. // new bool return used to see if anything was freed, used during z_malloc failure re-try
  460. //
  461. qboolean CM_DeleteCachedMap(qboolean bGuaranteedOkToDelete)
  462. {
  463. qboolean bActuallyFreedSomething = qfalse;
  464. if (bGuaranteedOkToDelete || !gbUsingCachedMapDataRightNow)
  465. {
  466. // dump cached disk image...
  467. //
  468. if (gpvCachedMapDiskImage)
  469. {
  470. Z_Free( gpvCachedMapDiskImage );
  471. gpvCachedMapDiskImage = NULL;
  472. bActuallyFreedSomething = qtrue;
  473. }
  474. gsCachedMapDiskImage[0] = '\0';
  475. // force map loader to ignore cached internal BSP structures for next level CM_LoadMap() call...
  476. //
  477. cmg.name[0] = '\0';
  478. }
  479. return bActuallyFreedSomething;
  480. }
  481. void CM_Free(void)
  482. {
  483. CM_ClearLevelPatches();
  484. visData.Release();
  485. Z_TagFree(TAG_BSP);
  486. }
  487. void R_LoadSurfaces( int count );
  488. void R_LoadPatches( void *verts, int vertlen,
  489. void *surfaces, int surfacelen );
  490. void R_LoadTriSurfs( void *indexdata, int indexlen,
  491. void *verts, int vertlen,
  492. void *surfaces, int surfacelen );
  493. void R_LoadFaces( void *indexdata, int indexlen,
  494. void *verts, int vertlen,
  495. void *surfaces, int surfacelen );
  496. void R_LoadFlares( void *surfaces, int surfacelen );
  497. extern void R_LoadShaders( void );
  498. extern void R_LoadLightmaps( void *data, int len, const char *psMapName );
  499. extern byte *fileBase;
  500. extern void UpdateLoadingAnimation();
  501. static void CM_LoadMap_Actual( const char *name, qboolean clientload, int *checksum ) {
  502. const int *buf = NULL;
  503. const int *surfBuf = NULL;
  504. static unsigned last_checksum;
  505. char lmName[MAX_QPATH];
  506. char stripName[MAX_QPATH];
  507. Lump outputLump;
  508. if ( !name || !name[0] ) {
  509. Com_Error( ERR_DROP, "CM_LoadMap: NULL name" );
  510. }
  511. #ifndef BSPC
  512. cm_noAreas = Cvar_Get ("cm_noAreas", "0", CVAR_CHEAT);
  513. cm_noCurves = Cvar_Get ("cm_noCurves", "0", CVAR_CHEAT);
  514. cm_playerCurveClip = Cvar_Get ("cm_playerCurveClip", "1", CVAR_ARCHIVE|CVAR_CHEAT );
  515. #endif
  516. Com_DPrintf( "CM_LoadMap( %s, %i )\n", name, clientload );
  517. if ( !strcmp( cmg.name, name ) && clientload ) {
  518. *checksum = last_checksum;
  519. return;
  520. }
  521. // free old stuff
  522. extern qboolean vidRestartReloadMap;
  523. int* ap;
  524. if (vidRestartReloadMap) ap = cmg.areaPortals;
  525. memset( &cmg, 0, sizeof( cmg ) );
  526. if (vidRestartReloadMap) cmg.areaPortals = ap;
  527. if ( !name[0] ) {
  528. cmg.numLeafs = 1;
  529. cmg.numClusters = 1;
  530. cmg.numAreas = 1;
  531. cmg.cmodels = (struct cmodel_s *) Z_Malloc( sizeof( *cmg.cmodels ), TAG_BSP, qtrue );
  532. *checksum = 0;
  533. return;
  534. }
  535. last_checksum = crc32(0, (const Bytef *)name, strlen(name));
  536. COM_StripExtension(name, stripName);
  537. UpdateLoadingAnimation();
  538. // load into heap
  539. outputLump.load(stripName, "shaders");
  540. CMod_LoadShaders( outputLump.data, outputLump.len );
  541. R_LoadShaders();
  542. UpdateLoadingAnimation();
  543. strcpy(lmName, name);
  544. outputLump.load(stripName, "lightmaps");
  545. R_LoadLightmaps( outputLump.data, outputLump.len, lmName);
  546. UpdateLoadingAnimation();
  547. {
  548. fileBase = NULL;
  549. outputLump.clear();
  550. Lump misc;
  551. misc.load(stripName, "misc");
  552. int num_surfs = *(int*)misc.data;
  553. misc.clear();
  554. R_LoadSurfaces(num_surfs);
  555. UpdateLoadingAnimation();
  556. Lump verts;
  557. verts.load(stripName, "verts");
  558. Lump patches;
  559. patches.load(stripName, "patches");
  560. UpdateLoadingAnimation();
  561. CMod_LoadPatches(verts.data, verts.len,
  562. patches.data, patches.len,
  563. num_surfs );
  564. R_LoadPatches(verts.data, verts.len,
  565. patches.data, patches.len);
  566. UpdateLoadingAnimation();
  567. patches.clear();
  568. Lump indexes;
  569. indexes.load(stripName, "indexes");
  570. Lump trisurfs;
  571. trisurfs.load(stripName, "trisurfs");
  572. UpdateLoadingAnimation();
  573. R_LoadTriSurfs(indexes.data, indexes.len,
  574. verts.data, verts.len,
  575. trisurfs.data, trisurfs.len);
  576. trisurfs.clear();
  577. UpdateLoadingAnimation();
  578. Lump faces;
  579. faces.load(stripName, "faces");
  580. R_LoadFaces(indexes.data, indexes.len,
  581. verts.data, verts.len,
  582. faces.data, faces.len);
  583. UpdateLoadingAnimation();
  584. Lump flares;
  585. flares.load(stripName, "flares");
  586. R_LoadFlares(flares.data, flares.len);
  587. }
  588. UpdateLoadingAnimation();
  589. outputLump.load(stripName, "leafs");
  590. CMod_LoadLeafs (outputLump.data, outputLump.len);
  591. outputLump.load(stripName, "leafbrushes");
  592. CMod_LoadLeafBrushes (outputLump.data, outputLump.len);
  593. UpdateLoadingAnimation();
  594. cmg.leafsurfaces = NULL;
  595. outputLump.load(stripName, "planes");
  596. CMod_LoadPlanes (outputLump.data, outputLump.len);
  597. outputLump.load(stripName, "brushsides");
  598. CMod_LoadBrushSides (outputLump.data, outputLump.len);
  599. outputLump.load(stripName, "brushes");
  600. CMod_LoadBrushes (outputLump.data, outputLump.len);
  601. UpdateLoadingAnimation();
  602. outputLump.load(stripName, "models");
  603. CMod_LoadSubmodels (outputLump.data, outputLump.len);
  604. outputLump.load(stripName, "nodes");
  605. CMod_LoadNodes (outputLump.data, outputLump.len);
  606. UpdateLoadingAnimation();
  607. outputLump.load(stripName, "entities");
  608. CMod_LoadEntityString (outputLump.data, outputLump.len);
  609. outputLump.load(stripName, "visibility");
  610. CMod_LoadVisibility( outputLump.data, outputLump.len);
  611. UpdateLoadingAnimation();
  612. TotalSubModels += cmg.numSubModels;
  613. CM_InitBoxHull ();
  614. *checksum = last_checksum;
  615. // do this whether or not the map was cached from last load...
  616. //
  617. CM_FloodAreaConnections ();
  618. UpdateLoadingAnimation();
  619. // allow this to be cached if it is loaded by the server
  620. if ( !clientload ) {
  621. Q_strncpyz( cmg.name, name, sizeof( cmg.name ) );
  622. }
  623. CM_CleanLeafCache();
  624. }
  625. // need a wrapper function around this because of multiple returns, need to ensure bool is correct...
  626. //
  627. void CM_LoadMap( const char *name, qboolean clientload, int *checksum )
  628. {
  629. CM_LoadMap_Actual( name, clientload, checksum );
  630. }
  631. qboolean CM_SameMap(char *server)
  632. {
  633. if (!cmg.name[0] || !server || !server[0])
  634. {
  635. return qfalse;
  636. }
  637. if (Q_stricmp(cmg.name, va("maps/%s.bsp", server)))
  638. {
  639. return qfalse;
  640. }
  641. return qtrue;
  642. }
  643. #ifndef _XBOX
  644. qboolean CM_HasTerrain(void)
  645. {
  646. if (cmg.landScape)
  647. return qtrue;
  648. return qfalse;
  649. }
  650. #endif
  651. /*
  652. ==================
  653. CM_ClearMap
  654. ==================
  655. */
  656. void CM_ClearMap( void )
  657. {
  658. int i;
  659. CM_OrOfAllContentsFlagsInMap = CONTENTS_BODY;
  660. #if !defined(BSPC)
  661. // CM_ShutdownShaderProperties();
  662. // MAT_Shutdown();
  663. #endif
  664. #ifndef _XBOX
  665. if (TheRandomMissionManager)
  666. {
  667. delete TheRandomMissionManager;
  668. TheRandomMissionManager = 0;
  669. }
  670. if (cmg.landScape)
  671. {
  672. delete cmg.landScape;
  673. cmg.landScape = 0;
  674. }
  675. #endif
  676. memset( &cmg, 0, sizeof( cmg ) );
  677. CM_ClearLevelPatches();
  678. for(i = 0; i < NumSubBSP; i++)
  679. {
  680. memset(&SubBSP[i], 0, sizeof(SubBSP[0]));
  681. }
  682. NumSubBSP = 0;
  683. TotalSubModels = 0;
  684. }
  685. int CM_TotalMapContents()
  686. {
  687. return CM_OrOfAllContentsFlagsInMap;
  688. }
  689. /*
  690. ==================
  691. CM_ClipHandleToModel
  692. ==================
  693. */
  694. cmodel_t *CM_ClipHandleToModel( clipHandle_t handle, clipMap_t **clipMap )
  695. {
  696. int i;
  697. int count;
  698. if ( handle < 0 )
  699. {
  700. Com_Error( ERR_DROP, "CM_ClipHandleToModel: bad handle %i", handle );
  701. }
  702. if ( handle < cmg.numSubModels )
  703. {
  704. if (clipMap)
  705. {
  706. *clipMap = &cmg;
  707. }
  708. return &cmg.cmodels[handle];
  709. }
  710. if ( handle == BOX_MODEL_HANDLE )
  711. {
  712. if (clipMap)
  713. {
  714. *clipMap = &cmg;
  715. }
  716. return &box_model;
  717. }
  718. count = cmg.numSubModels;
  719. for(i = 0; i < NumSubBSP; i++)
  720. {
  721. if (handle < count + SubBSP[i].numSubModels)
  722. {
  723. if (clipMap)
  724. {
  725. *clipMap = &SubBSP[i];
  726. }
  727. return &SubBSP[i].cmodels[handle - count];
  728. }
  729. count += SubBSP[i].numSubModels;
  730. }
  731. if ( handle < MAX_SUBMODELS )
  732. {
  733. Com_Error( ERR_DROP, "CM_ClipHandleToModel: bad handle %i < %i < %i",
  734. cmg.numSubModels, handle, MAX_SUBMODELS );
  735. }
  736. Com_Error( ERR_DROP, "CM_ClipHandleToModel: bad handle %i", handle + MAX_SUBMODELS );
  737. return NULL;
  738. }
  739. /*
  740. ==================
  741. CM_InlineModel
  742. ==================
  743. */
  744. clipHandle_t CM_InlineModel( int index ) {
  745. if ( index < 0 || index >= TotalSubModels ) {
  746. Com_Error (ERR_DROP, "CM_InlineModel: bad number (may need to re-BSP map?)");
  747. }
  748. return index;
  749. }
  750. int CM_NumClusters( void ) {
  751. return cmg.numClusters;
  752. }
  753. int CM_NumInlineModels( void ) {
  754. return cmg.numSubModels;
  755. }
  756. char *CM_EntityString( void ) {
  757. return cmg.entityString;
  758. }
  759. char *CM_SubBSPEntityString( int index )
  760. {
  761. return SubBSP[index].entityString;
  762. }
  763. int CM_LeafCluster( int leafnum ) {
  764. if (leafnum < 0 || leafnum >= cmg.numLeafs) {
  765. Com_Error (ERR_DROP, "CM_LeafCluster: bad number");
  766. }
  767. return cmg.leafs[leafnum].cluster;
  768. }
  769. int CM_LeafArea( int leafnum ) {
  770. if ( leafnum < 0 || leafnum >= cmg.numLeafs ) {
  771. Com_Error (ERR_DROP, "CM_LeafArea: bad number");
  772. }
  773. return cmg.leafs[leafnum].area;
  774. }
  775. //=======================================================================
  776. /*
  777. ===================
  778. CM_InitBoxHull
  779. Set up the planes and nodes so that the six floats of a bounding box
  780. can just be stored out and get a proper clipping hull structure.
  781. ===================
  782. */
  783. void CM_InitBoxHull (void)
  784. {
  785. int i;
  786. int side;
  787. cplane_t *p;
  788. cbrushside_t *s;
  789. box_planes = &cmg.planes[cmg.numPlanes];
  790. box_brush = &cmg.brushes[cmg.numBrushes];
  791. box_brush->numsides = 6;
  792. box_brush->sides = cmg.brushsides + cmg.numBrushSides;
  793. box_brush->contents = CONTENTS_BODY;
  794. box_model.leaf.numLeafBrushes = 1;
  795. // box_model.leaf.firstLeafBrush = cmg.numBrushes;
  796. box_model.leaf.firstLeafBrush = cmg.numLeafBrushes;
  797. cmg.leafbrushes[cmg.numLeafBrushes] = cmg.numBrushes;
  798. for (i=0 ; i<6 ; i++)
  799. {
  800. side = i&1;
  801. // brush sides
  802. s = &cmg.brushsides[cmg.numBrushSides+i];
  803. s->planeNum = cmg.numPlanes+i*2+side;
  804. s->shaderNum = cmg.numShaders;
  805. // planes
  806. p = &box_planes[i*2];
  807. p->type = i>>1;
  808. p->signbits = 0;
  809. VectorClear (p->normal);
  810. p->normal[i>>1] = 1;
  811. p = &box_planes[i*2+1];
  812. p->type = 3 + (i>>1);
  813. p->signbits = 0;
  814. VectorClear (p->normal);
  815. p->normal[i>>1] = -1;
  816. SetPlaneSignbits( p );
  817. }
  818. }
  819. /*
  820. ===================
  821. CM_HeadnodeForBox
  822. To keep everything totally uniform, bounding boxes are turned into small
  823. BSP trees instead of being compared directly.
  824. ===================
  825. */
  826. clipHandle_t CM_TempBoxModel( const vec3_t mins, const vec3_t maxs) {//, const int contents ) {
  827. box_planes[0].dist = maxs[0];
  828. box_planes[1].dist = -maxs[0];
  829. box_planes[2].dist = mins[0];
  830. box_planes[3].dist = -mins[0];
  831. box_planes[4].dist = maxs[1];
  832. box_planes[5].dist = -maxs[1];
  833. box_planes[6].dist = mins[1];
  834. box_planes[7].dist = -mins[1];
  835. box_planes[8].dist = maxs[2];
  836. box_planes[9].dist = -maxs[2];
  837. box_planes[10].dist = mins[2];
  838. box_planes[11].dist = -mins[2];
  839. VectorCopy( mins, box_brush->bounds[0] );
  840. VectorCopy( maxs, box_brush->bounds[1] );
  841. //FIXME: this is the "correct" way, but not the way JK2 was designed around... fix for further projects
  842. //box_brush->contents = contents;
  843. return BOX_MODEL_HANDLE;
  844. }
  845. /*
  846. ===================
  847. CM_ModelBounds
  848. ===================
  849. */
  850. void CM_ModelBounds( clipMap_t &cmg, clipHandle_t model, vec3_t mins, vec3_t maxs )
  851. {
  852. cmodel_t *cmod;
  853. cmod = CM_ClipHandleToModel( model );
  854. VectorCopy( cmod->mins, mins );
  855. VectorCopy( cmod->maxs, maxs );
  856. }
  857. /*
  858. ===================
  859. CM_RegisterTerrain
  860. Allows physics to examine the terrain data.
  861. ===================
  862. */
  863. #if !defined(BSPC)
  864. #if 0 // Removing terrain on Xbox
  865. CCMLandScape *CM_RegisterTerrain(const char *config, bool server)
  866. {
  867. thandle_t terrainId;
  868. CCMLandScape *ls;
  869. terrainId = atol(Info_ValueForKey(config, "terrainId"));
  870. if(terrainId && cmg.landScape)
  871. {
  872. // Already spawned so just return
  873. ls = cmg.landScape;
  874. ls->IncreaseRefCount();
  875. return(ls);
  876. }
  877. // Doesn't exist so create and link in
  878. //cmg.numTerrains++;
  879. ls = CM_InitTerrain(config, 1, server);
  880. // Increment for the next instance
  881. if (cmg.landScape)
  882. {
  883. Com_Error(ERR_DROP, "You can't have more than one terrain brush.");
  884. }
  885. cmg.landScape = ls;
  886. return(ls);
  887. }
  888. /*
  889. ===================
  890. CM_ShutdownTerrain
  891. ===================
  892. */
  893. void CM_ShutdownTerrain( thandle_t terrainId)
  894. {
  895. CCMLandScape *landscape;
  896. landscape = cmg.landScape;
  897. if (landscape)
  898. {
  899. landscape->DecreaseRefCount();
  900. if(landscape->GetRefCount() <= 0)
  901. {
  902. delete landscape;
  903. cmg.landScape = NULL;
  904. }
  905. }
  906. }
  907. #endif // No terrain on Xbox
  908. #endif
  909. int CM_LoadSubBSP(const char *name, qboolean clientload)
  910. {
  911. int i;
  912. // int checksum;
  913. int count;
  914. count = cmg.numSubModels;
  915. for(i = 0; i < NumSubBSP; i++)
  916. {
  917. if (!stricmp(name, SubBSP[i].name))
  918. {
  919. return count;
  920. }
  921. count += SubBSP[i].numSubModels;
  922. }
  923. if (NumSubBSP == MAX_SUB_BSP)
  924. {
  925. Com_Error (ERR_DROP, "CM_LoadSubBSP: too many unique sub BSPs");
  926. }
  927. #ifdef _XBOX
  928. assert(0); // MATT! - testing now - fix this later!
  929. #else
  930. CM_LoadMap_Actual( name, clientload, &checksum, SubBSP[NumSubBSP] );
  931. #endif
  932. NumSubBSP++;
  933. return count;
  934. }
  935. int CM_FindSubBSP(int modelIndex)
  936. {
  937. int i;
  938. int count;
  939. count = cmg.numSubModels;
  940. if (modelIndex < count)
  941. { // belongs to the main bsp
  942. return -1;
  943. }
  944. for(i = 0; i < NumSubBSP; i++)
  945. {
  946. count += SubBSP[i].numSubModels;
  947. if (modelIndex < count)
  948. {
  949. return i;
  950. }
  951. }
  952. return -1;
  953. }
  954. void CM_GetWorldBounds ( vec3_t mins, vec3_t maxs )
  955. {
  956. VectorCopy ( cmg.cmodels[0].mins, mins );
  957. VectorCopy ( cmg.cmodels[0].maxs, maxs );
  958. }
  959. int CM_ModelContents_Actual( clipHandle_t model, clipMap_t *cm )
  960. {
  961. cmodel_t *cmod;
  962. int contents = 0;
  963. int i;
  964. if (!cm)
  965. {
  966. cm = &cmg;
  967. }
  968. cmod = CM_ClipHandleToModel( model, &cm );
  969. //MCG ADDED - return the contents, too
  970. if( cmod->leaf.numLeafBrushes ) // check for brush
  971. {
  972. int brushNum;
  973. for ( i = cmod->leaf.firstLeafBrush; i < cmod->leaf.firstLeafBrush+cmod->leaf.numLeafBrushes; i++ )
  974. {
  975. brushNum = cm->leafbrushes[i];
  976. contents |= cm->brushes[brushNum].contents;
  977. }
  978. }
  979. if( cmod->leaf.numLeafSurfaces ) // if not brush, check for patch
  980. {
  981. int surfaceNum;
  982. for ( i = cmod->leaf.firstLeafSurface; i < cmod->leaf.firstLeafSurface+cmod->leaf.numLeafSurfaces; i++ )
  983. {
  984. surfaceNum = cm->leafsurfaces[i];
  985. if ( cm->surfaces[surfaceNum] != NULL )
  986. {//HERNH? How could we have a null surf within our cmod->leaf.numLeafSurfaces?
  987. contents |= cm->surfaces[surfaceNum]->contents;
  988. }
  989. }
  990. }
  991. return contents;
  992. }
  993. int CM_ModelContents( clipHandle_t model, int subBSPIndex )
  994. {
  995. if (subBSPIndex < 0)
  996. {
  997. return CM_ModelContents_Actual(model, NULL);
  998. }
  999. return CM_ModelContents_Actual(model, &SubBSP[subBSPIndex]);
  1000. }
  1001. //support for save/load games
  1002. /*
  1003. ===================
  1004. CM_WritePortalState
  1005. Writes the portal state to a savegame file
  1006. ===================
  1007. */
  1008. // having to proto this stuff again here is crap, but wtf?...
  1009. //
  1010. qboolean SG_Append(unsigned long chid, const void *data, int length);
  1011. int SG_Read(unsigned long chid, void *pvAddress, int iLength, void **ppvAddressPtr = NULL);
  1012. void CM_WritePortalState ()
  1013. {
  1014. SG_Append('PRTS', (void *)cmg.areaPortals, cmg.numAreas * cmg.numAreas * sizeof( *cmg.areaPortals ));
  1015. }
  1016. /*
  1017. ===================
  1018. CM_ReadPortalState
  1019. Reads the portal state from a savegame file
  1020. and recalculates the area connections
  1021. ===================
  1022. */
  1023. void CM_ReadPortalState ()
  1024. {
  1025. SG_Read('PRTS', (void *)cmg.areaPortals, cmg.numAreas * cmg.numAreas * sizeof( *cmg.areaPortals ));
  1026. CM_FloodAreaConnections ();
  1027. }