vis.cpp 47 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819
  1. /*
  2. VISIBLE INFORMATION SET -aka- V I S
  3. Code based on original code from Valve Software,
  4. Modified by Sean "Zoner" Cavanaugh ([email protected]) with permission.
  5. Modified by Tony "Merl" Moore ([email protected])
  6. Contains code by Skyler "Zipster" York ([email protected]) - Included with permission.
  7. */
  8. #ifdef SYSTEM_WIN32
  9. #pragma warning(disable:4996)
  10. #endif
  11. //amckern - 64bit - '<' Singed/Unsigned Mismatch
  12. #pragma warning(disable:4018)
  13. #include "vis.h"
  14. #ifdef ZHLT_NETVIS
  15. #include "zlib.h"
  16. #endif
  17. /*
  18. NOTES
  19. */
  20. int g_numportals = 0;
  21. unsigned g_portalleafs = 0;
  22. portal_t* g_portals;
  23. leaf_t* g_leafs;
  24. // AJM: MVD
  25. #ifdef HLVIS_MAXDIST
  26. byte* g_mightsee;
  27. visblocker_t g_visblockers[MAX_VISBLOCKERS];
  28. int g_numvisblockers = 0;
  29. #endif
  30. //
  31. static byte* vismap;
  32. static byte* vismap_p;
  33. static byte* vismap_end; // past visfile
  34. static int originalvismapsize;
  35. byte* g_uncompressed; // [bitbytes*portalleafs]
  36. unsigned g_bitbytes; // (portalleafs+63)>>3
  37. unsigned g_bitlongs;
  38. bool g_fastvis = DEFAULT_FASTVIS;
  39. bool g_fullvis = DEFAULT_FULLVIS;
  40. bool g_estimate = DEFAULT_ESTIMATE;
  41. bool g_chart = DEFAULT_CHART;
  42. bool g_info = DEFAULT_INFO;
  43. #ifdef HLVIS_MAXDIST
  44. // AJM: MVD
  45. unsigned int g_maxdistance = DEFAULT_MAXDISTANCE_RANGE;
  46. //bool g_postcompile = DEFAULT_POST_COMPILE;
  47. //
  48. #endif
  49. #ifdef ZHLT_PROGRESSFILE // AJM
  50. char* g_progressfile = DEFAULT_PROGRESSFILE; // "-progressfile path"
  51. #endif
  52. static int totalvis = 0;
  53. #if ZHLT_ZONES
  54. Zones* g_Zones;
  55. #endif
  56. #ifdef ZHLT_NETVIS
  57. // -- these are definitions and initializations of C/CPP common variables
  58. volatile int g_visportalindex = UNINITIALIZED_PORTAL_INDEX; // a client's portal index : current portalindex being worked on
  59. volatile int g_visportals = 0; // the total portals in the map
  60. volatile int g_visleafs = 0; // the total portal leafs in the map
  61. volatile int g_vislocalportal = 0; // number of portals solved locally
  62. volatile enum vis_states g_visstate = VIS_STARTUP; // current step of execution
  63. volatile enum vis_modes g_vismode = VIS_MODE_NULL; // style of execution (client or server)
  64. volatile int g_visleafthread = 0; // control flag (are we ready to leafthread)
  65. unsigned int g_rate = DEFAULT_NETVIS_RATE;
  66. volatile double g_starttime = 0; // Start time (from I_FloatTime())
  67. volatile unsigned long g_idletime = 0; // Accumulated idle time in milliseconds (rolls over after 46.7 days, hopefully a vis client wont run that long)
  68. volatile unsigned long g_serverindex = 0; // client only variable, server index for calculating percentage indicators on the client
  69. short g_port = DEFAULT_NETVIS_PORT;
  70. const char* g_server_addr = NULL;
  71. volatile bool g_bsp_downloaded = false; // Client variable
  72. volatile bool g_prt_downloaded = false; // Client variable
  73. volatile bool g_mightsee_downloaded = false; // Client variable
  74. char* g_bsp_image = NULL; // Client/Server variable : Server uses it for cache for connecting clients, clients download it to memory to not require filesystem usage
  75. char* g_prt_image = NULL; // Client/Server variable : Server uses it for cache for connecting clients, clients download it to memory to not require filesystem usage
  76. unsigned long g_bsp_compressed_size = 0; // Server variable
  77. unsigned long g_prt_compressed_size = 0; // Server variable
  78. unsigned long g_bsp_size = 0; // Server variable
  79. unsigned long g_prt_size = 0; // Server variable
  80. #endif
  81. #ifdef ZHLT_INFO_COMPILE_PARAMETERS
  82. // AJM: addded in
  83. // =====================================================================================
  84. // GetParamsFromEnt
  85. // this function is called from parseentity when it encounters the
  86. // info_compile_parameters entity. each tool should have its own version of this
  87. // to handle its own specific settings.
  88. // =====================================================================================
  89. void GetParamsFromEnt(entity_t* mapent)
  90. {
  91. int iTmp;
  92. Log("\nCompile Settings detected from info_compile_parameters entity\n");
  93. // verbose(choices) : "Verbose compile messages" : 0 = [ 0 : "Off" 1 : "On" ]
  94. iTmp = IntForKey(mapent, "verbose");
  95. if (iTmp == 1)
  96. {
  97. g_verbose = true;
  98. }
  99. else if (iTmp == 0)
  100. {
  101. g_verbose = false;
  102. }
  103. Log("%30s [ %-9s ]\n", "Compile Option", "setting");
  104. Log("%30s [ %-9s ]\n", "Verbose Compile Messages", g_verbose ? "on" : "off");
  105. // estimate(choices) :"Estimate Compile Times?" : 0 = [ 0: "Yes" 1: "No" ]
  106. if (IntForKey(mapent, "estimate"))
  107. {
  108. g_estimate = true;
  109. }
  110. else
  111. {
  112. g_estimate = false;
  113. }
  114. Log("%30s [ %-9s ]\n", "Estimate Compile Times", g_estimate ? "on" : "off");
  115. // priority(choices) : "Priority Level" : 0 = [ 0 : "Normal" 1 : "High" -1 : "Low" ]
  116. if (!strcmp(ValueForKey(mapent, "priority"), "1"))
  117. {
  118. g_threadpriority = eThreadPriorityHigh;
  119. Log("%30s [ %-9s ]\n", "Thread Priority", "high");
  120. }
  121. else if (!strcmp(ValueForKey(mapent, "priority"), "-1"))
  122. {
  123. g_threadpriority = eThreadPriorityLow;
  124. Log("%30s [ %-9s ]\n", "Thread Priority", "low");
  125. }
  126. /*
  127. hlvis(choices) : "HLVIS" : 2 =
  128. [
  129. 0 : "Off"
  130. 1 : "Fast"
  131. 2 : "Normal"
  132. 3 : "Full"
  133. ]
  134. */
  135. iTmp = IntForKey(mapent, "hlvis");
  136. if (iTmp == 0)
  137. {
  138. Fatal(assume_TOOL_CANCEL,
  139. "%s flag was not checked in info_compile_parameters entity, execution of %s cancelled", g_Program, g_Program);
  140. CheckFatal();
  141. }
  142. else if (iTmp == 1)
  143. {
  144. g_fastvis = true;
  145. g_fullvis = false;
  146. }
  147. else if (iTmp == 2)
  148. {
  149. g_fastvis = false;
  150. g_fullvis = false;
  151. }
  152. else if (iTmp == 3)
  153. {
  154. g_fullvis = true;
  155. g_fastvis = false;
  156. }
  157. Log("%30s [ %-9s ]\n", "Fast VIS", g_fastvis ? "on" : "off");
  158. Log("%30s [ %-9s ]\n", "Full VIS", g_fullvis ? "on" : "off" );
  159. ///////////////////
  160. Log("\n");
  161. }
  162. #endif
  163. // =====================================================================================
  164. // PlaneFromWinding
  165. // =====================================================================================
  166. static void PlaneFromWinding(winding_t* w, plane_t* plane)
  167. {
  168. vec3_t v1;
  169. vec3_t v2;
  170. // calc plane
  171. VectorSubtract(w->points[2], w->points[1], v1);
  172. VectorSubtract(w->points[0], w->points[1], v2);
  173. CrossProduct(v2, v1, plane->normal);
  174. VectorNormalize(plane->normal);
  175. plane->dist = DotProduct(w->points[0], plane->normal);
  176. }
  177. // =====================================================================================
  178. // NewWinding
  179. // =====================================================================================
  180. static winding_t* NewWinding(const int points)
  181. {
  182. winding_t* w;
  183. int size;
  184. if (points > MAX_POINTS_ON_WINDING)
  185. {
  186. Error("NewWinding: %i points > MAX_POINTS_ON_WINDING", points);
  187. }
  188. size = (int)((winding_t*)0)->points[points];
  189. w = (winding_t*)calloc(1, size);
  190. return w;
  191. }
  192. //=============================================================================
  193. /////////
  194. // NETVIS
  195. #ifdef ZHLT_NETVIS
  196. // =====================================================================================
  197. // GetPortalPtr
  198. // converts a portal index to a pointer
  199. // =====================================================================================
  200. portal_t* GetPortalPtr(const long index)
  201. {
  202. if (index < (g_numportals * 2))
  203. {
  204. return g_portals + index;
  205. }
  206. else
  207. {
  208. return (NULL);
  209. }
  210. }
  211. // =====================================================================================
  212. // GetNextPortalIndex
  213. // This is called by ClientSockets
  214. // =====================================================================================
  215. int GetNextPortalIndex()
  216. {
  217. int j;
  218. int best = NO_PORTAL_INDEX;
  219. portal_t* p;
  220. portal_t* tp;
  221. int min;
  222. ThreadLock();
  223. min = 99999;
  224. p = NULL;
  225. for (j = 0, tp = g_portals; j < g_numportals * 2; j++, tp++)
  226. {
  227. if (tp->nummightsee < min && tp->status == stat_none)
  228. {
  229. min = tp->nummightsee;
  230. p = tp;
  231. best = j;
  232. }
  233. }
  234. if (p)
  235. {
  236. p->status = stat_working;
  237. }
  238. else
  239. {
  240. best = NO_PORTAL_INDEX; // hack to return NO_PORTAL_INDEX to the queue'ing code
  241. }
  242. ThreadUnlock();
  243. return best;
  244. }
  245. // =====================================================================================
  246. // AllPortalsDone
  247. // returns true if all portals are done...
  248. // =====================================================================================
  249. static int AllPortalsDone()
  250. {
  251. const unsigned numportals = g_numportals * 2;
  252. portal_t* tp;
  253. unsigned j;
  254. for (j = 0, tp = g_portals; j < numportals; j++, tp++)
  255. {
  256. if (tp->status != stat_done)
  257. {
  258. return 0;
  259. }
  260. }
  261. return 1;
  262. }
  263. #endif
  264. // NETVIS
  265. ///////////
  266. // =====================================================================================
  267. // GetNextPortal
  268. // Returns the next portal for a thread to work on
  269. // Returns the portals from the least complex, so the later ones can reuse the earlier information.
  270. // =====================================================================================
  271. static portal_t* GetNextPortal()
  272. {
  273. int j;
  274. portal_t* p;
  275. portal_t* tp;
  276. int min;
  277. #ifdef ZHLT_NETVIS
  278. if (g_vismode == VIS_MODE_SERVER)
  279. {
  280. #else
  281. {
  282. if (GetThreadWork() == -1)
  283. {
  284. return NULL;
  285. }
  286. #endif
  287. ThreadLock();
  288. min = 99999;
  289. p = NULL;
  290. for (j = 0, tp = g_portals; j < g_numportals * 2; j++, tp++)
  291. {
  292. if (tp->nummightsee < min && tp->status == stat_none)
  293. {
  294. min = tp->nummightsee;
  295. p = tp;
  296. #ifdef ZHLT_NETVIS
  297. g_visportalindex = j;
  298. #endif
  299. }
  300. }
  301. if (p)
  302. {
  303. p->status = stat_working;
  304. }
  305. ThreadUnlock();
  306. return p;
  307. }
  308. #ifdef ZHLT_NETVIS
  309. else // AS CLIENT
  310. {
  311. while (getWorkFromClientQueue() == WAITING_FOR_PORTAL_INDEX)
  312. {
  313. unsigned delay = 100;
  314. g_idletime += delay; // This is the only point where the portal work goes idle, so its easy to add up just how idle it is.
  315. if (!isConnectedToServer())
  316. {
  317. Error("Unexepected disconnect from server(1)\n");
  318. }
  319. NetvisSleep(delay);
  320. }
  321. if (g_visportalindex == NO_PORTAL_INDEX)
  322. {
  323. g_visstate = VIS_CLIENT_DONE;
  324. Send_VIS_GOING_DOWN(g_ClientSession);
  325. return NULL;
  326. }
  327. // convert index to pointer
  328. tp = GetPortalPtr(g_visportalindex);
  329. if (tp)
  330. {
  331. tp->status = stat_working;
  332. }
  333. return (tp);
  334. }
  335. #endif
  336. }
  337. #ifdef HLVIS_MAXDIST
  338. // AJM: MVD
  339. // =====================================================================================
  340. // DecompressAll
  341. // =====================================================================================
  342. void DecompressAll(void)
  343. {
  344. int i;
  345. byte *dest;
  346. for(i = 0; i < g_portalleafs; i++)
  347. {
  348. dest = g_uncompressed + i * g_bitbytes;
  349. DecompressVis((const unsigned char*)(g_dvisdata + (byte)g_dleafs[i + 1].visofs), dest, g_bitbytes);
  350. }
  351. }
  352. // AJM: MVD
  353. // =====================================================================================
  354. // CompressAll
  355. // =====================================================================================
  356. void CompressAll(void)
  357. {
  358. int i, x = 0;
  359. byte *dest;
  360. byte *src;
  361. byte compressed[MAX_MAP_LEAFS / 8];
  362. vismap_p = vismap;
  363. for(i = 0; i < g_portalleafs; i++)
  364. {
  365. memset(&compressed, 0, sizeof(compressed));
  366. src = g_uncompressed + i * g_bitbytes;
  367. // Compress all leafs into global compression buffer
  368. x = CompressVis(src, g_bitbytes, compressed, sizeof(compressed));
  369. dest = vismap_p;
  370. vismap_p += x;
  371. if (vismap_p > vismap_end)
  372. {
  373. Error("Vismap expansion overflow");
  374. }
  375. g_dleafs[i + 1].visofs = dest - vismap; // leaf 0 is a common solid
  376. memcpy(dest, compressed, x);
  377. }
  378. }
  379. #endif // HLVIS_MAXDIST
  380. // =====================================================================================
  381. // LeafThread
  382. // =====================================================================================
  383. #ifdef SYSTEM_WIN32
  384. #pragma warning(push)
  385. #pragma warning(disable:4100) // unreferenced formal parameter
  386. #endif
  387. #ifndef ZHLT_NETVIS
  388. static void LeafThread(int unused)
  389. {
  390. portal_t* p;
  391. while (1)
  392. {
  393. if (!(p = GetNextPortal()))
  394. {
  395. return;
  396. }
  397. PortalFlow(p);
  398. Verbose("portal:%4i mightsee:%4i cansee:%4i\n", (int)(p - g_portals), p->nummightsee, p->numcansee);
  399. }
  400. }
  401. #endif //!ZHLT_NETVIS
  402. #ifdef ZHLT_NETVIS
  403. static void LeafThread(int unused)
  404. {
  405. if (g_vismode == VIS_MODE_CLIENT)
  406. {
  407. portal_t* p;
  408. g_visstate = VIS_BASE_PORTAL_VIS_SERVER_WAIT;
  409. Send_VIS_LEAFTHREAD(g_visleafs, g_visportals, g_bitbytes);
  410. while (!g_visleafthread)
  411. {
  412. if (!isConnectedToServer())
  413. {
  414. Error("Unexepected disconnect from server(2)\n");
  415. }
  416. NetvisSleep(100);
  417. }
  418. g_visstate = VIS_PORTAL_FLOW;
  419. Send_VIS_WANT_FULL_SYNC();
  420. while (!g_NetvisAbort)
  421. {
  422. if (!(p = GetNextPortal()))
  423. {
  424. return;
  425. }
  426. PortalFlow(p);
  427. Send_VIS_DONE_PORTAL(g_visportalindex, p);
  428. g_vislocalportal++;
  429. }
  430. }
  431. else if (g_vismode == VIS_MODE_SERVER)
  432. {
  433. #if 0
  434. // Server does zero work in ZHLT netvis
  435. g_visstate = VIS_WAIT_CLIENTS;
  436. while (!g_NetvisAbort)
  437. {
  438. NetvisSleep(1000);
  439. if (AllPortalsDone())
  440. {
  441. g_visstate = VIS_POST;
  442. return;
  443. }
  444. }
  445. #else
  446. portal_t* p;
  447. g_visstate = VIS_WAIT_CLIENTS;
  448. while (!g_NetvisAbort)
  449. {
  450. if (!(p = GetNextPortal()))
  451. {
  452. if (AllPortalsDone())
  453. {
  454. g_visstate = VIS_POST;
  455. return;
  456. }
  457. NetvisSleep(1000); // No need to churn while waiting on slow clients
  458. continue;
  459. }
  460. PortalFlow(p);
  461. g_vislocalportal++;
  462. }
  463. #endif
  464. }
  465. else
  466. {
  467. hlassume(false, assume_VALID_NETVIS_STATE);
  468. }
  469. }
  470. #endif
  471. #ifdef SYSTEM_WIN32
  472. #pragma warning(pop)
  473. #endif
  474. // =====================================================================================
  475. // LeafFlow
  476. // Builds the entire visibility list for a leaf
  477. // =====================================================================================
  478. static void LeafFlow(const int leafnum)
  479. {
  480. leaf_t* leaf;
  481. byte* outbuffer;
  482. byte compressed[MAX_MAP_LEAFS / 8];
  483. unsigned i;
  484. unsigned j;
  485. int k;
  486. int tmp;
  487. int numvis;
  488. byte* dest;
  489. portal_t* p;
  490. //
  491. // flow through all portals, collecting visible bits
  492. //
  493. memset(compressed, 0, sizeof(compressed));
  494. outbuffer = g_uncompressed + leafnum * g_bitbytes;
  495. leaf = &g_leafs[leafnum];
  496. tmp = 0;
  497. const unsigned offset = leafnum >> 3;
  498. const unsigned bit = (1 << (leafnum & 7));
  499. for (i = 0; i < leaf->numportals; i++)
  500. {
  501. p = leaf->portals[i];
  502. if (p->status != stat_done)
  503. {
  504. Error("portal not done (leaf %d)", leafnum);
  505. }
  506. {
  507. byte* dst = outbuffer;
  508. byte* src = p->visbits;
  509. for (j=0; j<g_bitbytes; j++, dst++, src++)
  510. {
  511. *dst |= *src;
  512. }
  513. }
  514. if ((tmp == 0) && (outbuffer[offset] & bit))
  515. {
  516. tmp = 1;
  517. Warning("Leaf portals saw into leaf");
  518. Log(" Problem at portal between leaves %i and %i:\n ", leafnum, p->leaf);
  519. for (k = 0; k < p->winding->numpoints; k++)
  520. {
  521. Log(" (%4.3f %4.3f %4.3f)\n", p->winding->points[k][0], p->winding->points[k][1], p->winding->points[k][2]);
  522. }
  523. Log("\n");
  524. }
  525. }
  526. outbuffer[offset] |= bit;
  527. numvis = 0;
  528. for (i = 0; i < (g_portalleafs >> 3); i++)
  529. {
  530. byte tmp_byte = outbuffer[i];
  531. int k;
  532. for (k=0;k<8;k++)
  533. {
  534. if (tmp_byte & (1 << k))
  535. {
  536. numvis++;
  537. }
  538. }
  539. }
  540. //
  541. // compress the bit string
  542. //
  543. Verbose("leaf %4i : %4i visible\n", leafnum, numvis);
  544. totalvis += numvis;
  545. i = CompressVis(outbuffer, g_bitbytes, compressed, sizeof(compressed));
  546. dest = vismap_p;
  547. vismap_p += i;
  548. if (vismap_p > vismap_end)
  549. {
  550. Error("Vismap expansion overflow");
  551. }
  552. g_dleafs[leafnum + 1].visofs = dest - vismap; // leaf 0 is a common solid
  553. memcpy(dest, compressed, i);
  554. }
  555. // =====================================================================================
  556. // CalcPortalVis
  557. // =====================================================================================
  558. static void CalcPortalVis()
  559. {
  560. #ifndef ZHLT_NETVIS
  561. // g_fastvis just uses mightsee for a very loose bound
  562. if (g_fastvis)
  563. {
  564. int i;
  565. for (i = 0; i < g_numportals * 2; i++)
  566. {
  567. g_portals[i].visbits = g_portals[i].mightsee;
  568. g_portals[i].status = stat_done;
  569. }
  570. return;
  571. }
  572. #endif
  573. #ifdef ZHLT_NETVIS
  574. LeafThread(0);
  575. #else
  576. NamedRunThreadsOn(g_numportals * 2, g_estimate, LeafThread);
  577. #endif
  578. }
  579. //////////////
  580. // ZHLT_NETVIS
  581. #ifdef ZHLT_NETVIS
  582. // =====================================================================================
  583. // CalcVis
  584. // =====================================================================================
  585. static void CalcVis()
  586. {
  587. unsigned lastpercent = 0;
  588. int x, size;
  589. if (g_vismode == VIS_MODE_SERVER)
  590. {
  591. g_visstate = VIS_BASE_PORTAL_VIS;
  592. Log("BasePortalVis: \n");
  593. for (x = 0, size = g_numportals * 2; x < size; x++)
  594. {
  595. unsigned percent = (x * 100 / size);
  596. if (percent && (percent != lastpercent) && ((percent % 10) == 0))
  597. {
  598. lastpercent = percent;
  599. printf("%d%%....", percent);
  600. }
  601. BasePortalVis(x);
  602. }
  603. printf("\n");
  604. }
  605. else
  606. {
  607. Send_VIS_WANT_MIGHTSEE_DATA();
  608. while(!g_mightsee_downloaded)
  609. {
  610. if (!isConnectedToServer())
  611. {
  612. Error("Unexepected disconnect from server(3)\n");
  613. }
  614. NetvisSleep(100);
  615. }
  616. }
  617. g_visportals = g_numportals;
  618. g_visleafs = g_portalleafs;
  619. g_starttime = I_FloatTime();
  620. StartStatusDisplayThread(g_rate);
  621. CalcPortalVis();
  622. if (g_vismode == VIS_MODE_SERVER)
  623. {
  624. unsigned int i;
  625. for (i = 0; i < g_portalleafs; i++)
  626. {
  627. LeafFlow(i);
  628. }
  629. Log("Average leafs visible: %i\n", totalvis / g_portalleafs);
  630. }
  631. }
  632. #endif
  633. #ifndef ZHLT_NETVIS
  634. #ifdef HLVIS_MAXDIST
  635. // AJM: MVD
  636. // =====================================================================================
  637. // GetVisBlock
  638. // =====================================================================================
  639. visblocker_t *GetVisBlock(char *name)
  640. {
  641. int i;
  642. visblocker_t *v;
  643. for(i = 0, v = &g_visblockers[0]; i < g_numvisblockers; i++, v++)
  644. {
  645. if(!strcmp(name, v->name))
  646. return v;
  647. }
  648. return NULL;
  649. }
  650. // AJM: MVD
  651. // =====================================================================================
  652. // InitVisBlock
  653. // =====================================================================================
  654. static void InitVisBlock(void)
  655. {
  656. char visfile[_MAX_PATH];
  657. int i;
  658. int x = 0;
  659. int num_blocks;
  660. int num_sides;
  661. strcpy_s(visfile, g_Mapname);
  662. DefaultExtension(visfile, ".vis");
  663. if(!q_exists(visfile))
  664. return;
  665. FILE *fp = fopen(visfile, "r");
  666. if(!fp)
  667. return;
  668. while(!feof(fp))
  669. {
  670. fscanf_s(fp, "%s\n", g_visblockers[x].name);
  671. fscanf_s(fp, "%d\n", &num_blocks);
  672. for(i = 0; i < num_blocks; i++)
  673. {
  674. fscanf_s(fp, "%s\n", g_visblockers[x].blocknames[i]);
  675. }
  676. g_visblockers[x].numnames = num_blocks;
  677. fscanf_s(fp, "%d\n", &num_sides);
  678. for(i = 0; i < num_sides; i++)
  679. {
  680. fscanf_s(fp, "%f %f %f %f\n", &g_visblockers[x].planes[i].normal[0],
  681. &g_visblockers[x].planes[i].normal[1],
  682. &g_visblockers[x].planes[i].normal[2],
  683. &g_visblockers[x].planes[i].dist);
  684. }
  685. g_visblockers[x].numplanes = num_sides;
  686. g_visblockers[x].numleafs = 0;
  687. x++;
  688. }
  689. g_numvisblockers = x;
  690. }
  691. // AJM: MVD
  692. // =====================================================================================
  693. // SetupVisBlockLeafs
  694. // Set up the leafs for the visblocker
  695. // =====================================================================================
  696. static void SetupVisBlockLeafs(void)
  697. {
  698. int i, j, k, l, q;
  699. visblocker_t *v;
  700. leaf_t *leaf;
  701. portal_t *p;
  702. plane_t *plane;
  703. float dist;
  704. for(i = 0, v = &g_visblockers[0]; i < g_numvisblockers; i++, v++)
  705. {
  706. for(j = 0, leaf = &g_leafs[0]; j < g_portalleafs; j++, leaf++)
  707. {
  708. for(q = 0, p = leaf->portals[0]; q < leaf->numportals; q++, p++)
  709. {
  710. for(k = 0; k < p->winding->numpoints; k++)
  711. {
  712. for(l = 0, plane = &v->planes[0]; l < v->numplanes; l++, plane++)
  713. {
  714. dist = DotProduct(p->winding->points[k], plane->normal) - plane->dist;
  715. if(dist > ON_EPSILON)
  716. goto PostLoop;
  717. }
  718. }
  719. }
  720. PostLoop:
  721. if(q != leaf->numportals)
  722. continue;
  723. // If we reach this point, then the portal is completely inside the visblocker
  724. v->blockleafs[v->numleafs++] = j;
  725. }
  726. }
  727. }
  728. // AJM: MVD
  729. // =====================================================================================
  730. // SaveVisData
  731. // =====================================================================================
  732. void SaveVisData(const char *filename)
  733. {
  734. int i;
  735. FILE *fp = fopen(filename, "wb");
  736. if(!fp)
  737. return;
  738. SafeWrite(fp, g_dvisdata, (vismap_p - g_dvisdata));
  739. // BUG BUG BUG!
  740. // Leaf offsets need to be saved too!!!!
  741. for(i = 0; i < g_numleafs; i++)
  742. {
  743. SafeWrite(fp, &g_dleafs[i].visofs, sizeof(int));
  744. }
  745. fclose(fp);
  746. }
  747. // AJM: MVD
  748. // =====================================================================================
  749. // ResetPortalStatus
  750. // FIX: Used to reset p->status to stat_none; now it justs frees p->visbits
  751. // =====================================================================================
  752. void ResetPortalStatus(void)
  753. {
  754. int i;
  755. portal_t* p = g_portals;
  756. for(i = 0; i < g_numportals * 2; i++, p++)
  757. {
  758. //p->status = stat_none;
  759. free(p->visbits);
  760. }
  761. }
  762. #endif // HLVIS_MAXDIST
  763. // AJM UNDONE HLVIS_MAXDIST THIS!!!!!!!!!!!!!
  764. // AJM: MVD modified
  765. // =====================================================================================
  766. // CalcVis
  767. // =====================================================================================
  768. static void CalcVis()
  769. {
  770. unsigned i;
  771. char visdatafile[_MAX_PATH];
  772. strcpy_s(visdatafile, g_Mapname);
  773. DefaultExtension(visdatafile, ".vdt");
  774. // Remove this file
  775. _unlink(visdatafile);
  776. /* if(g_postcompile)
  777. {
  778. if(!g_maxdistance)
  779. {
  780. Error("Must use -maxdistance parameter with -postcompile");
  781. }
  782. // Decompress everything so we can edit it
  783. DecompressAll();
  784. NamedRunThreadsOn(g_portalleafs, g_estimate, PostMaxDistVis);
  785. // Recompress it
  786. CompressAll();
  787. }
  788. else
  789. {*/
  790. // InitVisBlock();
  791. // SetupVisBlockLeafs();
  792. NamedRunThreadsOn(g_numportals * 2, g_estimate, BasePortalVis);
  793. // if(g_numvisblockers)
  794. // NamedRunThreadsOn(g_numvisblockers, g_estimate, BlockVis);
  795. // First do a normal VIS, save to file, then redo MaxDistVis
  796. CalcPortalVis();
  797. //
  798. // assemble the leaf vis lists by oring and compressing the portal lists
  799. //
  800. for (i = 0; i < g_portalleafs; i++)
  801. {
  802. LeafFlow(i);
  803. }
  804. Log("Average leafs visible: %i\n", totalvis / g_portalleafs);
  805. if(g_maxdistance)
  806. {
  807. totalvis = 0;
  808. Log("Saving visdata to %s...\n", visdatafile);
  809. SaveVisData(visdatafile);
  810. // We need to reset the uncompressed variable and portal visbits
  811. free(g_uncompressed);
  812. g_uncompressed = (byte*)calloc(g_portalleafs, g_bitbytes);
  813. vismap_p = g_dvisdata;
  814. // We don't need to run BasePortalVis again
  815. NamedRunThreadsOn(g_portalleafs, g_estimate, MaxDistVis);
  816. // No need to run this - MaxDistVis now writes directly to visbits after the initial VIS
  817. //CalcPortalVis();
  818. for (i = 0; i < g_portalleafs; i++)
  819. {
  820. LeafFlow(i);
  821. }
  822. // FIX: Used to reset p->status to stat_none; now it justs frees p->visbits
  823. ResetPortalStatus();
  824. Log("Average maxdistance leafs visible: %i\n", totalvis / g_portalleafs);
  825. }
  826. // }
  827. }
  828. #endif //!ZHLT_NETVIS
  829. // ZHLT_NETVIS
  830. //////////////
  831. // =====================================================================================
  832. // CheckNullToken
  833. // =====================================================================================
  834. static INLINE void FASTCALL CheckNullToken(const char*const token)
  835. {
  836. if (token == NULL)
  837. {
  838. Error("LoadPortals: Damaged or invalid .prt file\n");
  839. }
  840. }
  841. // =====================================================================================
  842. // LoadPortals
  843. // =====================================================================================
  844. static void LoadPortals(char* portal_image)
  845. {
  846. int i, j;
  847. portal_t* p;
  848. leaf_t* l;
  849. int numpoints;
  850. winding_t* w;
  851. int leafnums[2];
  852. plane_t plane;
  853. const char* const seperators = " ()\r\n\t";
  854. char* token;
  855. token = strtok(portal_image, seperators);
  856. CheckNullToken(token);
  857. if (!sscanf_s(token, "%u", &g_portalleafs))
  858. {
  859. Error("LoadPortals: failed to read header: number of leafs");
  860. }
  861. token = strtok(NULL, seperators);
  862. CheckNullToken(token);
  863. if (!sscanf_s(token, "%i", &g_numportals))
  864. {
  865. Error("LoadPortals: failed to read header: number of portals");
  866. }
  867. Log("Portalleafs: %4i\n", g_portalleafs);
  868. Log("Numportals: %4i\n", g_numportals);
  869. g_bitbytes = ((g_portalleafs + 63) & ~63) >> 3;
  870. g_bitlongs = g_bitbytes / sizeof(long);
  871. // each file portal is split into two memory portals
  872. g_portals = (portal_t*)calloc(2 * g_numportals, sizeof(portal_t));
  873. g_leafs = (leaf_t*)calloc(g_portalleafs, sizeof(leaf_t));
  874. originalvismapsize = g_portalleafs * ((g_portalleafs + 7) / 8);
  875. vismap = vismap_p = g_dvisdata;
  876. vismap_end = vismap + MAX_MAP_VISIBILITY;
  877. for (i = 0, p = g_portals; i < g_numportals; i++)
  878. {
  879. unsigned rval = 0;
  880. token = strtok(NULL, seperators);
  881. CheckNullToken(token);
  882. rval += sscanf_s(token, "%i", &numpoints);
  883. token = strtok(NULL, seperators);
  884. CheckNullToken(token);
  885. rval += sscanf_s(token, "%i", &leafnums[0]);
  886. token = strtok(NULL, seperators);
  887. CheckNullToken(token);
  888. rval += sscanf_s(token, "%i", &leafnums[1]);
  889. if (rval != 3)
  890. {
  891. Error("LoadPortals: reading portal %i", i);
  892. }
  893. if (numpoints > MAX_POINTS_ON_WINDING)
  894. {
  895. Error("LoadPortals: portal %i has too many points", i);
  896. }
  897. if (((unsigned)leafnums[0] > g_portalleafs) || ((unsigned)leafnums[1] > g_portalleafs))
  898. {
  899. Error("LoadPortals: reading portal %i", i);
  900. }
  901. w = p->winding = NewWinding(numpoints);
  902. w->original = true;
  903. w->numpoints = numpoints;
  904. for (j = 0; j < numpoints; j++)
  905. {
  906. int k;
  907. double v[3];
  908. unsigned rval = 0;
  909. token = strtok(NULL, seperators);
  910. CheckNullToken(token);
  911. rval += sscanf_s(token, "%lf", &v[0]);
  912. token = strtok(NULL, seperators);
  913. CheckNullToken(token);
  914. rval += sscanf_s(token, "%lf", &v[1]);
  915. token = strtok(NULL, seperators);
  916. CheckNullToken(token);
  917. rval += sscanf_s(token, "%lf", &v[2]);
  918. // scanf into double, then assign to vec_t
  919. if (rval != 3)
  920. {
  921. Error("LoadPortals: reading portal %i", i);
  922. }
  923. for (k = 0; k < 3; k++)
  924. {
  925. w->points[j][k] = v[k];
  926. }
  927. }
  928. // calc plane
  929. PlaneFromWinding(w, &plane);
  930. // create forward portal
  931. l = &g_leafs[leafnums[0]];
  932. hlassume(l->numportals < MAX_PORTALS_ON_LEAF, assume_MAX_PORTALS_ON_LEAF);
  933. l->portals[l->numportals] = p;
  934. l->numportals++;
  935. p->winding = w;
  936. VectorSubtract(vec3_origin, plane.normal, p->plane.normal);
  937. p->plane.dist = -plane.dist;
  938. p->leaf = leafnums[1];
  939. p++;
  940. // create backwards portal
  941. l = &g_leafs[leafnums[1]];
  942. hlassume(l->numportals < MAX_PORTALS_ON_LEAF, assume_MAX_PORTALS_ON_LEAF);
  943. l->portals[l->numportals] = p;
  944. l->numportals++;
  945. p->winding = NewWinding(w->numpoints);
  946. p->winding->numpoints = w->numpoints;
  947. for (j = 0; j < w->numpoints; j++)
  948. {
  949. VectorCopy(w->points[w->numpoints - 1 - j], p->winding->points[j]);
  950. }
  951. p->plane = plane;
  952. p->leaf = leafnums[0];
  953. p++;
  954. }
  955. }
  956. // =====================================================================================
  957. // LoadPortalsByFilename
  958. // =====================================================================================
  959. static void LoadPortalsByFilename(const char* const filename)
  960. {
  961. char* file_image;
  962. if (!q_exists(filename))
  963. {
  964. Error("Portal file '%s' does not exist, cannot vis the map\n", filename);
  965. }
  966. LoadFile(filename, &file_image);
  967. LoadPortals(file_image);
  968. free(file_image);
  969. }
  970. #if ZHLT_ZONES
  971. // =====================================================================================
  972. // AssignPortalsToZones
  973. // =====================================================================================
  974. static void AssignPortalsToZones()
  975. {
  976. hlassert(g_Zones != NULL);
  977. UINT32 count = 0;
  978. portal_t* p;
  979. UINT32 x;
  980. UINT32 tmp[20];
  981. memset(tmp, 0, sizeof(tmp));
  982. UINT32 numportals = g_numportals * 2;
  983. for (x=0, p=g_portals; x<numportals; x++, p++)
  984. {
  985. BoundingBox bounds;
  986. winding_t* w = p->winding;
  987. UINT32 numpoints = w->numpoints;
  988. UINT32 y;
  989. for (y=0; y<numpoints; y++)
  990. {
  991. bounds.add(w->points[y]);
  992. }
  993. p->zone = g_Zones->getZoneFromBounds(bounds);
  994. tmp[p->zone]++;
  995. if (p->zone)
  996. {
  997. count++;
  998. }
  999. }
  1000. for (x=0; x<15; x++)
  1001. {
  1002. Log("Zone %2u : %u\n", x, tmp[x]);
  1003. }
  1004. Log("%u of %u portals were contained in func_vis zones\n", count, numportals);
  1005. }
  1006. #endif
  1007. // =====================================================================================
  1008. // Usage
  1009. // =====================================================================================
  1010. static void Usage()
  1011. {
  1012. Banner();
  1013. Log("\n-= %s Options =-\n\n", g_Program);
  1014. Log(" -full : Full vis\n");
  1015. Log(" -fast : Fast vis\n\n");
  1016. #ifdef ZHLT_NETVIS
  1017. Log(" -connect address : Connect to netvis server at address as a client\n");
  1018. Log(" -server : Run as the netvis server\n");
  1019. Log(" -port # : Use a non-standard port for netvis\n");
  1020. Log(" -rate # : Alter the display update rate\n\n");
  1021. #endif
  1022. Log(" -texdata # : Alter maximum texture memory limit (in kb)\n");
  1023. Log(" -lightdata # : Alter maximum texture memory limit (in kb)\n");
  1024. Log(" -chart : display bsp statitics\n");
  1025. Log(" -low | -high : run program an altered priority level\n");
  1026. Log(" -nolog : don't generate the compile logfiles\n");
  1027. Log(" -threads # : manually specify the number of threads to run\n");
  1028. Log(" -noconcolors : Disable Windows console text coloring\n");
  1029. #ifdef SYSTEM_WIN32
  1030. Log(" -estimate : display estimated time during compile\n");
  1031. #endif
  1032. #ifdef ZHLT_PROGRESSFILE // AJM
  1033. Log(" -progressfile path : specify the path to a file for progress estimate output\n");
  1034. #endif
  1035. #ifdef SYSTEM_POSIX
  1036. Log(" -noestimate : do not display continuous compile time estimates\n");
  1037. #endif
  1038. #ifdef HLVIS_MAXDIST // AJM: MVD
  1039. Log(" -maxdistance # : Alter the maximum distance for visibility\n");
  1040. #endif
  1041. Log(" -verbose : compile with verbose messages\n");
  1042. Log(" -noinfo : Do not show tool configuration information\n");
  1043. Log(" -dev # : compile with developer message\n\n");
  1044. Log(" mapfile : The mapfile to compile\n\n");
  1045. #ifdef ZHLT_NETVIS
  1046. Log("\n"
  1047. "In netvis one computer must be the server and all the rest are the clients.\n"
  1048. "The server should be started with : netvis -server mapname\n"
  1049. "And the clients should be started with : netvis -connect servername\n"
  1050. "\n"
  1051. "The default socket it uses is 21212 and can be changed with -port\n"
  1052. "The default update rate is 60 seconds and can be changed with -rate\n");
  1053. #endif
  1054. exit(1);
  1055. }
  1056. // =====================================================================================
  1057. // Settings
  1058. // =====================================================================================
  1059. static void Settings()
  1060. {
  1061. char* tmp;
  1062. if (!g_info)
  1063. {
  1064. return;
  1065. }
  1066. Log("\n-= Current %s Settings =-\n", g_Program);
  1067. Log("Name | Setting | Default\n" "-------------------|-------------|-------------------------\n");
  1068. // ZHLT Common Settings
  1069. if (DEFAULT_NUMTHREADS == -1)
  1070. {
  1071. Log("threads [ %9d ] [ Varies ]\n", g_numthreads);
  1072. }
  1073. else
  1074. {
  1075. Log("threads [ %9d ] [ %9d ]\n", g_numthreads, DEFAULT_NUMTHREADS);
  1076. }
  1077. Log("verbose [ %9s ] [ %9s ]\n", g_verbose ? "on" : "off", DEFAULT_VERBOSE ? "on" : "off");
  1078. Log("log [ %9s ] [ %9s ]\n", g_log ? "on" : "off", DEFAULT_LOG ? "on" : "off");
  1079. Log("developer [ %9d ] [ %9d ]\n", g_developer, DEFAULT_DEVELOPER);
  1080. Log("chart [ %9s ] [ %9s ]\n", g_chart ? "on" : "off", DEFAULT_CHART ? "on" : "off");
  1081. Log("estimate [ %9s ] [ %9s ]\n", g_estimate ? "on" : "off", DEFAULT_ESTIMATE ? "on" : "off");
  1082. Log("max texture memory [ %9d ] [ %9d ]\n", g_max_map_miptex, DEFAULT_MAX_MAP_MIPTEX);
  1083. #ifdef HLVIS_MAXDIST // AJM: MVD
  1084. Log("max vis distance [ %9d ] [ %9d ]\n", g_maxdistance, DEFAULT_MAXDISTANCE_RANGE);
  1085. //Log("max dist only [ %9s ] [ %9s ]\n", g_postcompile ? "on" : "off", DEFAULT_POST_COMPILE ? "on" : "off");
  1086. #endif
  1087. switch (g_threadpriority)
  1088. {
  1089. case eThreadPriorityNormal:
  1090. default:
  1091. tmp = "Normal";
  1092. break;
  1093. case eThreadPriorityLow:
  1094. tmp = "Low";
  1095. break;
  1096. case eThreadPriorityHigh:
  1097. tmp = "High";
  1098. break;
  1099. }
  1100. Log("priority [ %9s ] [ %9s ]\n", tmp, "Normal");
  1101. Log("\n");
  1102. // HLVIS Specific Settings
  1103. Log("fast vis [ %9s ] [ %9s ]\n", g_fastvis ? "on" : "off", DEFAULT_FASTVIS ? "on" : "off");
  1104. Log("full vis [ %9s ] [ %9s ]\n", g_fullvis ? "on" : "off", DEFAULT_FULLVIS ? "on" : "off");
  1105. #ifdef ZHLT_NETVIS
  1106. if (g_vismode == VIS_MODE_SERVER)
  1107. {
  1108. Log("netvis mode [ Server ]\n");
  1109. }
  1110. else if (g_vismode == VIS_MODE_CLIENT)
  1111. {
  1112. Log("netvis mode [ Client, connected to %s ]\n", g_server_addr);
  1113. }
  1114. Log("netvis port [ %9d ] [ %9d ]\n", g_port, DEFAULT_NETVIS_PORT);
  1115. Log("netvis display rate [ %9d ] [ %9d ]\n", g_rate, DEFAULT_NETVIS_RATE);
  1116. #endif
  1117. Log("\n\n");
  1118. }
  1119. // =====================================================================================
  1120. // main
  1121. // =====================================================================================
  1122. int main(const int argc, char** argv)
  1123. {
  1124. char portalfile[_MAX_PATH];
  1125. char source[_MAX_PATH];
  1126. int i;
  1127. double start, end;
  1128. const char* mapname_from_arg = NULL;
  1129. #ifdef ZHLT_NETVIS
  1130. g_Program = "netvis";
  1131. #else
  1132. g_Program = "hlvis";
  1133. #endif
  1134. if (argc == 1)
  1135. {
  1136. Usage();
  1137. }
  1138. for (i = 1; i < argc; i++)
  1139. {
  1140. if (!strcasecmp(argv[i], "-threads"))
  1141. {
  1142. if (i < argc)
  1143. {
  1144. g_numthreads = atoi(argv[++i]);
  1145. if (g_numthreads < 1)
  1146. {
  1147. Log("Expected value of at least 1 for '-threads'\n");
  1148. Usage();
  1149. }
  1150. }
  1151. else
  1152. {
  1153. Usage();
  1154. }
  1155. }
  1156. #ifdef SYSTEM_WIN32
  1157. else if (!strcasecmp(argv[i], "-estimate"))
  1158. {
  1159. g_estimate = true;
  1160. }
  1161. #endif
  1162. #ifdef SYSTEM_POSIX
  1163. else if (!strcasecmp(argv[i], "-noestimate"))
  1164. {
  1165. g_estimate = false;
  1166. }
  1167. #endif
  1168. #ifdef ZHLT_NETVIS
  1169. else if (!strcasecmp(argv[i], "-server"))
  1170. {
  1171. g_vismode = VIS_MODE_SERVER;
  1172. }
  1173. else if (!strcasecmp(argv[i], "-connect"))
  1174. {
  1175. if (i < argc)
  1176. {
  1177. g_vismode = VIS_MODE_CLIENT;
  1178. g_server_addr = argv[++i];
  1179. }
  1180. else
  1181. {
  1182. Usage();
  1183. }
  1184. }
  1185. else if (!strcasecmp(argv[i], "-port"))
  1186. {
  1187. if (i < argc)
  1188. {
  1189. g_port = atoi(argv[++i]);
  1190. }
  1191. else
  1192. {
  1193. Usage();
  1194. }
  1195. }
  1196. else if (!strcasecmp(argv[i], "-rate"))
  1197. {
  1198. if (i < argc)
  1199. {
  1200. g_rate = atoi(argv[++i]);
  1201. }
  1202. else
  1203. {
  1204. Usage();
  1205. }
  1206. if (g_rate < 5)
  1207. {
  1208. Log("Minimum -rate is 5, setting to 5 seconds\n");
  1209. g_rate = 5;
  1210. }
  1211. if (g_rate > 900)
  1212. {
  1213. Log("Maximum -rate is 900, setting to 900 seconds\n");
  1214. g_rate = 900;
  1215. }
  1216. }
  1217. #endif
  1218. #ifndef ZHLT_NETVIS
  1219. else if (!strcasecmp(argv[i], "-fast"))
  1220. {
  1221. Log("g_fastvis = true\n");
  1222. g_fastvis = true;
  1223. }
  1224. #endif
  1225. else if (!strcasecmp(argv[i], "-full"))
  1226. {
  1227. g_fullvis = true;
  1228. }
  1229. else if (!strcasecmp(argv[i], "-dev"))
  1230. {
  1231. if (i < argc)
  1232. {
  1233. g_developer = (developer_level_t)atoi(argv[++i]);
  1234. }
  1235. else
  1236. {
  1237. Usage();
  1238. }
  1239. }
  1240. else if (!strcasecmp(argv[i], "-verbose"))
  1241. {
  1242. g_verbose = true;
  1243. }
  1244. else if (!strcasecmp(argv[i], "-noinfo"))
  1245. {
  1246. g_info = false;
  1247. }
  1248. else if (!strcasecmp(argv[i], "-chart"))
  1249. {
  1250. g_chart = true;
  1251. }
  1252. else if (!strcasecmp(argv[i], "-low"))
  1253. {
  1254. g_threadpriority = eThreadPriorityLow;
  1255. }
  1256. else if (!strcasecmp(argv[i], "-high"))
  1257. {
  1258. g_threadpriority = eThreadPriorityHigh;
  1259. }
  1260. else if (!strcasecmp(argv[i], "-nolog"))
  1261. {
  1262. g_log = false;
  1263. }
  1264. else if (!strcasecmp(argv[i], "-texdata"))
  1265. {
  1266. if (i < argc)
  1267. {
  1268. int x = atoi(argv[++i]) * 1024;
  1269. if (x > g_max_map_miptex)
  1270. {
  1271. g_max_map_miptex = x;
  1272. }
  1273. }
  1274. else
  1275. {
  1276. Usage();
  1277. }
  1278. }
  1279. else if (!strcasecmp(argv[i], "-lightdata"))
  1280. {
  1281. if (i < argc)
  1282. {
  1283. int x = atoi(argv[++i]) * 1024;
  1284. if (x > g_max_map_miptex)
  1285. {
  1286. g_max_map_miptex = x;
  1287. }
  1288. }
  1289. else
  1290. {
  1291. Usage();
  1292. }
  1293. }
  1294. #ifdef ZHLT_PROGRESSFILE // AJM
  1295. else if (!strcasecmp(argv[i], "-progressfile"))
  1296. {
  1297. if (i < argc)
  1298. {
  1299. g_progressfile = argv[++i];
  1300. }
  1301. else
  1302. {
  1303. Log("Error: -progressfile: expected path to progress file following parameter\n");
  1304. Usage();
  1305. }
  1306. }
  1307. #endif
  1308. #ifdef HLVIS_MAXDIST
  1309. // AJM: MVD
  1310. else if(!strcasecmp(argv[i], "-maxdistance"))
  1311. {
  1312. if(i < argc)
  1313. {
  1314. g_maxdistance = abs(atoi(argv[++i]));
  1315. }
  1316. else
  1317. {
  1318. Usage();
  1319. }
  1320. }
  1321. /* else if(!strcasecmp(argv[i], "-postcompile"))
  1322. {
  1323. g_postcompile = true;
  1324. }*/
  1325. #endif
  1326. // SILENCER -->
  1327. else if (!strcasecmp(argv[i], "-noconcolors"))
  1328. {
  1329. g_noConColors = true;
  1330. }
  1331. // <-- SILENCER
  1332. else if (argv[i][0] == '-')
  1333. {
  1334. Log("Unknown option \"%s\"", argv[i]);
  1335. Usage();
  1336. }
  1337. else if (!mapname_from_arg)
  1338. {
  1339. mapname_from_arg = argv[i];
  1340. }
  1341. else
  1342. {
  1343. Log("Unknown option \"%s\"\n", argv[i]);
  1344. Usage();
  1345. }
  1346. }
  1347. #ifdef ZHLT_NETVIS
  1348. threads_InitCrit();
  1349. if (g_vismode == VIS_MODE_CLIENT)
  1350. {
  1351. ConnectToServer(g_server_addr, g_port);
  1352. while (!isConnectedToServer())
  1353. {
  1354. NetvisSleep(100);
  1355. }
  1356. Send_VIS_LOGIN();
  1357. while (!g_clientid)
  1358. {
  1359. if (!isConnectedToServer())
  1360. {
  1361. Error("Unexepected disconnect from server(4)\n");
  1362. }
  1363. NetvisSleep(100);
  1364. }
  1365. mapname_from_arg = "proxy";
  1366. }
  1367. else if (g_vismode == VIS_MODE_SERVER)
  1368. {
  1369. StartNetvisSocketServer(g_port);
  1370. if (!mapname_from_arg)
  1371. {
  1372. Log("No mapfile specified\n");
  1373. Usage();
  1374. }
  1375. }
  1376. else
  1377. {
  1378. Log("Netvis must be run either as a server (-server)\n" "or as a client (-connect servername)\n\n");
  1379. Usage();
  1380. }
  1381. #else
  1382. if (!mapname_from_arg)
  1383. {
  1384. Log("No mapfile specified\n");
  1385. Usage();
  1386. }
  1387. #endif
  1388. #ifdef ZHLT_NETVIS
  1389. if (g_vismode == VIS_MODE_CLIENT)
  1390. {
  1391. g_log = false;
  1392. }
  1393. #endif
  1394. safe_strncpy(g_Mapname, mapname_from_arg, _MAX_PATH);
  1395. FlipSlashes(g_Mapname);
  1396. StripExtension(g_Mapname);
  1397. OpenLog(g_clientid);
  1398. atexit(CloseLog);
  1399. ThreadSetDefault();
  1400. ThreadSetPriority(g_threadpriority);
  1401. LogStart(argc, argv);
  1402. #ifdef ZHLT_NETVIS
  1403. if (g_vismode == VIS_MODE_CLIENT)
  1404. {
  1405. Log("ZHLT NETVIS Client #%d\n", g_clientid);
  1406. g_log = false;
  1407. }
  1408. else
  1409. {
  1410. Log("ZHLT NETVIS Server\n");
  1411. }
  1412. #endif
  1413. CheckForErrorLog();
  1414. dtexdata_init();
  1415. atexit(dtexdata_free);
  1416. // END INIT
  1417. // BEGIN VIS
  1418. start = I_FloatTime();
  1419. safe_strncpy(source, g_Mapname, _MAX_PATH);
  1420. safe_strncat(source, ".bsp", _MAX_PATH);
  1421. safe_strncpy(portalfile, g_Mapname, _MAX_PATH);
  1422. safe_strncat(portalfile, ".prt", _MAX_PATH);
  1423. #ifdef ZHLT_NETVIS
  1424. if (g_vismode == VIS_MODE_SERVER)
  1425. {
  1426. LoadBSPFile(source);
  1427. LoadPortalsByFilename(portalfile);
  1428. char* bsp_image;
  1429. char* prt_image;
  1430. g_bsp_size = LoadFile(source, &bsp_image);
  1431. g_prt_size = LoadFile(portalfile, &prt_image);
  1432. g_bsp_compressed_size = (g_bsp_size * 1.01) + 12; // Magic numbers come from zlib documentation
  1433. g_prt_compressed_size = (g_prt_size * 1.01) + 12; // Magic numbers come from zlib documentation
  1434. char* bsp_compressed_image = (char*)malloc(g_bsp_compressed_size);
  1435. char* prt_compressed_image = (char*)malloc(g_prt_compressed_size);
  1436. int rval;
  1437. rval = compress2((byte*)bsp_compressed_image, &g_bsp_compressed_size, (byte*)bsp_image, g_bsp_size, 5);
  1438. if (rval != Z_OK)
  1439. {
  1440. Error("zlib Compression error with bsp image\n");
  1441. }
  1442. rval = compress2((byte*)prt_compressed_image, &g_prt_compressed_size, (byte*)prt_image, g_prt_size, 7);
  1443. if (rval != Z_OK)
  1444. {
  1445. Error("zlib Compression error with prt image\n");
  1446. }
  1447. free(bsp_image);
  1448. free(prt_image);
  1449. g_bsp_image = bsp_compressed_image;
  1450. g_prt_image = prt_compressed_image;
  1451. }
  1452. else if (g_vismode == VIS_MODE_CLIENT)
  1453. {
  1454. Send_VIS_WANT_BSP_DATA();
  1455. while (!g_bsp_downloaded)
  1456. {
  1457. if (!isConnectedToServer())
  1458. {
  1459. Error("Unexepected disconnect from server(5)\n");
  1460. }
  1461. NetvisSleep(100);
  1462. }
  1463. Send_VIS_WANT_PRT_DATA();
  1464. while (!g_prt_downloaded)
  1465. {
  1466. if (!isConnectedToServer())
  1467. {
  1468. Error("Unexepected disconnect from server(6)\n");
  1469. }
  1470. NetvisSleep(100);
  1471. }
  1472. LoadPortals(g_prt_image);
  1473. free(g_prt_image);
  1474. }
  1475. #else // NOT ZHLT_NETVIS
  1476. LoadBSPFile(source);
  1477. ParseEntities(NULL, NULL);
  1478. LoadPortalsByFilename(portalfile);
  1479. # if ZHLT_ZONES
  1480. g_Zones = MakeZones();
  1481. AssignPortalsToZones();
  1482. # endif
  1483. #endif
  1484. Settings();
  1485. g_uncompressed = (byte*)calloc(g_portalleafs, g_bitbytes);
  1486. CalcVis();
  1487. #ifdef ZHLT_NETVIS
  1488. if (g_vismode == VIS_MODE_SERVER)
  1489. {
  1490. g_visdatasize = vismap_p - g_dvisdata;
  1491. Log("g_visdatasize: %i compressed from %i\n", g_visdatasize, originalvismapsize);
  1492. if (g_chart)
  1493. {
  1494. PrintBSPFileSizes();
  1495. }
  1496. WriteBSPFile(source);
  1497. end = I_FloatTime();
  1498. LogTimeElapsed(end - start);
  1499. free(g_uncompressed);
  1500. // END VIS
  1501. #ifndef SYSTEM_WIN32
  1502. // Talk about cheese . . .
  1503. StopNetvisSocketServer();
  1504. #endif
  1505. }
  1506. else if (g_vismode == VIS_MODE_CLIENT)
  1507. {
  1508. #ifndef SYSTEM_WIN32
  1509. // Dont ask . .
  1510. DisconnectFromServer();
  1511. #endif
  1512. end = I_FloatTime();
  1513. LogTimeElapsed(end - start);
  1514. free(g_uncompressed);
  1515. // END VIS
  1516. }
  1517. threads_UninitCrit();
  1518. #else // NOT ZHLT_NETVIS
  1519. g_visdatasize = vismap_p - g_dvisdata;
  1520. Log("g_visdatasize: %i compressed from %i\n", g_visdatasize, originalvismapsize);
  1521. if (g_chart)
  1522. {
  1523. PrintBSPFileSizes();
  1524. }
  1525. WriteBSPFile(source);
  1526. end = I_FloatTime();
  1527. LogTimeElapsed(end - start);
  1528. free(g_uncompressed);
  1529. // END VIS
  1530. #endif // ZHLT_NETVIS
  1531. return 0;
  1532. }