r_main.c 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423
  1. /*
  2. Copyright (C) 1997-2001 Id Software, Inc.
  3. This program is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU General Public License
  5. as published by the Free Software Foundation; either version 2
  6. of the License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. See the GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  14. */
  15. // r_main.c
  16. #include "r_local.h"
  17. viddef_t vid;
  18. refimport_t ri;
  19. unsigned d_8to24table[256];
  20. entity_t r_worldentity;
  21. char skyname[MAX_QPATH];
  22. float skyrotate;
  23. vec3_t skyaxis;
  24. image_t *sky_images[6];
  25. refdef_t r_newrefdef;
  26. model_t *currentmodel;
  27. model_t *r_worldmodel;
  28. byte r_warpbuffer[WARP_WIDTH * WARP_HEIGHT];
  29. swstate_t sw_state;
  30. void *colormap;
  31. vec3_t viewlightvec;
  32. alight_t r_viewlighting = {128, 192, viewlightvec};
  33. float r_time1;
  34. int r_numallocatededges;
  35. float r_aliasuvscale = 1.0;
  36. int r_outofsurfaces;
  37. int r_outofedges;
  38. qboolean r_dowarp;
  39. mvertex_t *r_pcurrentvertbase;
  40. int c_surf;
  41. int r_maxsurfsseen, r_maxedgesseen, r_cnumsurfs;
  42. qboolean r_surfsonstack;
  43. int r_clipflags;
  44. //
  45. // view origin
  46. //
  47. vec3_t vup, base_vup;
  48. vec3_t vpn, base_vpn;
  49. vec3_t vright, base_vright;
  50. vec3_t r_origin;
  51. //
  52. // screen size info
  53. //
  54. oldrefdef_t r_refdef;
  55. float xcenter, ycenter;
  56. float xscale, yscale;
  57. float xscaleinv, yscaleinv;
  58. float xscaleshrink, yscaleshrink;
  59. float aliasxscale, aliasyscale, aliasxcenter, aliasycenter;
  60. int r_screenwidth;
  61. float verticalFieldOfView;
  62. float xOrigin, yOrigin;
  63. mplane_t screenedge[4];
  64. //
  65. // refresh flags
  66. //
  67. int r_framecount = 1; // so frame counts initialized to 0 don't match
  68. int r_visframecount;
  69. int d_spanpixcount;
  70. int r_polycount;
  71. int r_drawnpolycount;
  72. int r_wholepolycount;
  73. int *pfrustum_indexes[4];
  74. int r_frustum_indexes[4*6];
  75. mleaf_t *r_viewleaf;
  76. int r_viewcluster, r_oldviewcluster;
  77. image_t *r_notexture_mip;
  78. float da_time1, da_time2, dp_time1, dp_time2, db_time1, db_time2, rw_time1, rw_time2;
  79. float se_time1, se_time2, de_time1, de_time2;
  80. void R_MarkLeaves (void);
  81. cvar_t *r_lefthand;
  82. cvar_t *sw_aliasstats;
  83. cvar_t *sw_allow_modex;
  84. cvar_t *sw_clearcolor;
  85. cvar_t *sw_drawflat;
  86. cvar_t *sw_draworder;
  87. cvar_t *sw_maxedges;
  88. cvar_t *sw_maxsurfs;
  89. cvar_t *sw_mode;
  90. cvar_t *sw_reportedgeout;
  91. cvar_t *sw_reportsurfout;
  92. cvar_t *sw_stipplealpha;
  93. cvar_t *sw_surfcacheoverride;
  94. cvar_t *sw_waterwarp;
  95. cvar_t *r_drawworld;
  96. cvar_t *r_drawentities;
  97. cvar_t *r_dspeeds;
  98. cvar_t *r_fullbright;
  99. cvar_t *r_lerpmodels;
  100. cvar_t *r_novis;
  101. cvar_t *r_speeds;
  102. cvar_t *r_lightlevel; //FIXME HACK
  103. cvar_t *vid_fullscreen;
  104. cvar_t *vid_gamma;
  105. //PGM
  106. cvar_t *sw_lockpvs;
  107. //PGM
  108. #define STRINGER(x) "x"
  109. #if !id386
  110. // r_vars.c
  111. // all global and static refresh variables are collected in a contiguous block
  112. // to avoid cache conflicts.
  113. //-------------------------------------------------------
  114. // global refresh variables
  115. //-------------------------------------------------------
  116. // FIXME: make into one big structure, like cl or sv
  117. // FIXME: do separately for refresh engine and driver
  118. // d_vars.c
  119. // all global and static refresh variables are collected in a contiguous block
  120. // to avoid cache conflicts.
  121. //-------------------------------------------------------
  122. // global refresh variables
  123. //-------------------------------------------------------
  124. // FIXME: make into one big structure, like cl or sv
  125. // FIXME: do separately for refresh engine and driver
  126. float d_sdivzstepu, d_tdivzstepu, d_zistepu;
  127. float d_sdivzstepv, d_tdivzstepv, d_zistepv;
  128. float d_sdivzorigin, d_tdivzorigin, d_ziorigin;
  129. fixed16_t sadjust, tadjust, bbextents, bbextentt;
  130. pixel_t *cacheblock;
  131. int cachewidth;
  132. pixel_t *d_viewbuffer;
  133. short *d_pzbuffer;
  134. unsigned int d_zrowbytes;
  135. unsigned int d_zwidth;
  136. #endif // !id386
  137. byte r_notexture_buffer[1024];
  138. /*
  139. ==================
  140. R_InitTextures
  141. ==================
  142. */
  143. void R_InitTextures (void)
  144. {
  145. int x,y, m;
  146. byte *dest;
  147. // create a simple checkerboard texture for the default
  148. r_notexture_mip = (image_t *)&r_notexture_buffer;
  149. r_notexture_mip->width = r_notexture_mip->height = 16;
  150. r_notexture_mip->pixels[0] = &r_notexture_buffer[sizeof(image_t)];
  151. r_notexture_mip->pixels[1] = r_notexture_mip->pixels[0] + 16*16;
  152. r_notexture_mip->pixels[2] = r_notexture_mip->pixels[1] + 8*8;
  153. r_notexture_mip->pixels[3] = r_notexture_mip->pixels[2] + 4*4;
  154. for (m=0 ; m<4 ; m++)
  155. {
  156. dest = r_notexture_mip->pixels[m];
  157. for (y=0 ; y< (16>>m) ; y++)
  158. for (x=0 ; x< (16>>m) ; x++)
  159. {
  160. if ( (y< (8>>m) ) ^ (x< (8>>m) ) )
  161. *dest++ = 0;
  162. else
  163. *dest++ = 0xff;
  164. }
  165. }
  166. }
  167. /*
  168. ================
  169. R_InitTurb
  170. ================
  171. */
  172. void R_InitTurb (void)
  173. {
  174. int i;
  175. for (i=0 ; i<1280 ; i++)
  176. {
  177. sintable[i] = AMP + sin(i*3.14159*2/CYCLE)*AMP;
  178. intsintable[i] = AMP2 + sin(i*3.14159*2/CYCLE)*AMP2; // AMP2, not 20
  179. blanktable[i] = 0; //PGM
  180. }
  181. }
  182. void R_ImageList_f( void );
  183. void R_Register (void)
  184. {
  185. sw_aliasstats = ri.Cvar_Get ("sw_polymodelstats", "0", 0);
  186. sw_allow_modex = ri.Cvar_Get( "sw_allow_modex", "1", CVAR_ARCHIVE );
  187. sw_clearcolor = ri.Cvar_Get ("sw_clearcolor", "2", 0);
  188. sw_drawflat = ri.Cvar_Get ("sw_drawflat", "0", 0);
  189. sw_draworder = ri.Cvar_Get ("sw_draworder", "0", 0);
  190. sw_maxedges = ri.Cvar_Get ("sw_maxedges", STRINGER(MAXSTACKSURFACES), 0);
  191. sw_maxsurfs = ri.Cvar_Get ("sw_maxsurfs", "0", 0);
  192. sw_mipcap = ri.Cvar_Get ("sw_mipcap", "0", 0);
  193. sw_mipscale = ri.Cvar_Get ("sw_mipscale", "1", 0);
  194. sw_reportedgeout = ri.Cvar_Get ("sw_reportedgeout", "0", 0);
  195. sw_reportsurfout = ri.Cvar_Get ("sw_reportsurfout", "0", 0);
  196. sw_stipplealpha = ri.Cvar_Get( "sw_stipplealpha", "0", CVAR_ARCHIVE );
  197. sw_surfcacheoverride = ri.Cvar_Get ("sw_surfcacheoverride", "0", 0);
  198. sw_waterwarp = ri.Cvar_Get ("sw_waterwarp", "1", 0);
  199. sw_mode = ri.Cvar_Get( "sw_mode", "0", CVAR_ARCHIVE );
  200. r_lefthand = ri.Cvar_Get( "hand", "0", CVAR_USERINFO | CVAR_ARCHIVE );
  201. r_speeds = ri.Cvar_Get ("r_speeds", "0", 0);
  202. r_fullbright = ri.Cvar_Get ("r_fullbright", "0", 0);
  203. r_drawentities = ri.Cvar_Get ("r_drawentities", "1", 0);
  204. r_drawworld = ri.Cvar_Get ("r_drawworld", "1", 0);
  205. r_dspeeds = ri.Cvar_Get ("r_dspeeds", "0", 0);
  206. r_lightlevel = ri.Cvar_Get ("r_lightlevel", "0", 0);
  207. r_lerpmodels = ri.Cvar_Get( "r_lerpmodels", "1", 0 );
  208. r_novis = ri.Cvar_Get( "r_novis", "0", 0 );
  209. vid_fullscreen = ri.Cvar_Get( "vid_fullscreen", "0", CVAR_ARCHIVE );
  210. vid_gamma = ri.Cvar_Get( "vid_gamma", "1.0", CVAR_ARCHIVE );
  211. ri.Cmd_AddCommand ("modellist", Mod_Modellist_f);
  212. ri.Cmd_AddCommand( "screenshot", R_ScreenShot_f );
  213. ri.Cmd_AddCommand( "imagelist", R_ImageList_f );
  214. sw_mode->modified = true; // force us to do mode specific stuff later
  215. vid_gamma->modified = true; // force us to rebuild the gamma table later
  216. //PGM
  217. sw_lockpvs = ri.Cvar_Get ("sw_lockpvs", "0", 0);
  218. //PGM
  219. }
  220. void R_UnRegister (void)
  221. {
  222. ri.Cmd_RemoveCommand( "screenshot" );
  223. ri.Cmd_RemoveCommand ("modellist");
  224. ri.Cmd_RemoveCommand( "imagelist" );
  225. }
  226. /*
  227. ===============
  228. R_Init
  229. ===============
  230. */
  231. qboolean R_Init( void *hInstance, void *wndProc )
  232. {
  233. R_InitImages ();
  234. Mod_Init ();
  235. Draw_InitLocal ();
  236. R_InitTextures ();
  237. R_InitTurb ();
  238. view_clipplanes[0].leftedge = true;
  239. view_clipplanes[1].rightedge = true;
  240. view_clipplanes[1].leftedge = view_clipplanes[2].leftedge =
  241. view_clipplanes[3].leftedge = false;
  242. view_clipplanes[0].rightedge = view_clipplanes[2].rightedge =
  243. view_clipplanes[3].rightedge = false;
  244. r_refdef.xOrigin = XCENTERING;
  245. r_refdef.yOrigin = YCENTERING;
  246. // TODO: collect 386-specific code in one place
  247. #if id386
  248. Sys_MakeCodeWriteable ((long)R_EdgeCodeStart,
  249. (long)R_EdgeCodeEnd - (long)R_EdgeCodeStart);
  250. Sys_SetFPCW (); // get bit masks for FPCW (FIXME: is this id386?)
  251. #endif // id386
  252. r_aliasuvscale = 1.0;
  253. R_Register ();
  254. Draw_GetPalette ();
  255. SWimp_Init( hInstance, wndProc );
  256. // create the window
  257. R_BeginFrame( 0 );
  258. ri.Con_Printf (PRINT_ALL, "ref_soft version: "REF_VERSION"\n");
  259. return true;
  260. }
  261. /*
  262. ===============
  263. R_Shutdown
  264. ===============
  265. */
  266. void R_Shutdown (void)
  267. {
  268. // free z buffer
  269. if (d_pzbuffer)
  270. {
  271. free (d_pzbuffer);
  272. d_pzbuffer = NULL;
  273. }
  274. // free surface cache
  275. if (sc_base)
  276. {
  277. D_FlushCaches ();
  278. free (sc_base);
  279. sc_base = NULL;
  280. }
  281. // free colormap
  282. if (vid.colormap)
  283. {
  284. free (vid.colormap);
  285. vid.colormap = NULL;
  286. }
  287. R_UnRegister ();
  288. Mod_FreeAll ();
  289. R_ShutdownImages ();
  290. SWimp_Shutdown();
  291. }
  292. /*
  293. ===============
  294. R_NewMap
  295. ===============
  296. */
  297. void R_NewMap (void)
  298. {
  299. r_viewcluster = -1;
  300. r_cnumsurfs = sw_maxsurfs->value;
  301. if (r_cnumsurfs <= MINSURFACES)
  302. r_cnumsurfs = MINSURFACES;
  303. if (r_cnumsurfs > NUMSTACKSURFACES)
  304. {
  305. surfaces = malloc (r_cnumsurfs * sizeof(surf_t));
  306. surface_p = surfaces;
  307. surf_max = &surfaces[r_cnumsurfs];
  308. r_surfsonstack = false;
  309. // surface 0 doesn't really exist; it's just a dummy because index 0
  310. // is used to indicate no edge attached to surface
  311. surfaces--;
  312. R_SurfacePatch ();
  313. }
  314. else
  315. {
  316. r_surfsonstack = true;
  317. }
  318. r_maxedgesseen = 0;
  319. r_maxsurfsseen = 0;
  320. r_numallocatededges = sw_maxedges->value;
  321. if (r_numallocatededges < MINEDGES)
  322. r_numallocatededges = MINEDGES;
  323. if (r_numallocatededges <= NUMSTACKEDGES)
  324. {
  325. auxedges = NULL;
  326. }
  327. else
  328. {
  329. auxedges = malloc (r_numallocatededges * sizeof(edge_t));
  330. }
  331. }
  332. /*
  333. ===============
  334. R_MarkLeaves
  335. Mark the leaves and nodes that are in the PVS for the current
  336. cluster
  337. ===============
  338. */
  339. void R_MarkLeaves (void)
  340. {
  341. byte *vis;
  342. mnode_t *node;
  343. int i;
  344. mleaf_t *leaf;
  345. int cluster;
  346. if (r_oldviewcluster == r_viewcluster && !r_novis->value && r_viewcluster != -1)
  347. return;
  348. // development aid to let you run around and see exactly where
  349. // the pvs ends
  350. if (sw_lockpvs->value)
  351. return;
  352. r_visframecount++;
  353. r_oldviewcluster = r_viewcluster;
  354. if (r_novis->value || r_viewcluster == -1 || !r_worldmodel->vis)
  355. {
  356. // mark everything
  357. for (i=0 ; i<r_worldmodel->numleafs ; i++)
  358. r_worldmodel->leafs[i].visframe = r_visframecount;
  359. for (i=0 ; i<r_worldmodel->numnodes ; i++)
  360. r_worldmodel->nodes[i].visframe = r_visframecount;
  361. return;
  362. }
  363. vis = Mod_ClusterPVS (r_viewcluster, r_worldmodel);
  364. for (i=0,leaf=r_worldmodel->leafs ; i<r_worldmodel->numleafs ; i++, leaf++)
  365. {
  366. cluster = leaf->cluster;
  367. if (cluster == -1)
  368. continue;
  369. if (vis[cluster>>3] & (1<<(cluster&7)))
  370. {
  371. node = (mnode_t *)leaf;
  372. do
  373. {
  374. if (node->visframe == r_visframecount)
  375. break;
  376. node->visframe = r_visframecount;
  377. node = node->parent;
  378. } while (node);
  379. }
  380. }
  381. #if 0
  382. for (i=0 ; i<r_worldmodel->vis->numclusters ; i++)
  383. {
  384. if (vis[i>>3] & (1<<(i&7)))
  385. {
  386. node = (mnode_t *)&r_worldmodel->leafs[i]; // FIXME: cluster
  387. do
  388. {
  389. if (node->visframe == r_visframecount)
  390. break;
  391. node->visframe = r_visframecount;
  392. node = node->parent;
  393. } while (node);
  394. }
  395. }
  396. #endif
  397. }
  398. /*
  399. ** R_DrawNullModel
  400. **
  401. ** IMPLEMENT THIS!
  402. */
  403. void R_DrawNullModel( void )
  404. {
  405. }
  406. /*
  407. =============
  408. R_DrawEntitiesOnList
  409. =============
  410. */
  411. void R_DrawEntitiesOnList (void)
  412. {
  413. int i;
  414. qboolean translucent_entities = false;
  415. if (!r_drawentities->value)
  416. return;
  417. // all bmodels have already been drawn by the edge list
  418. for (i=0 ; i<r_newrefdef.num_entities ; i++)
  419. {
  420. currententity = &r_newrefdef.entities[i];
  421. if ( currententity->flags & RF_TRANSLUCENT )
  422. {
  423. translucent_entities = true;
  424. continue;
  425. }
  426. if ( currententity->flags & RF_BEAM )
  427. {
  428. modelorg[0] = -r_origin[0];
  429. modelorg[1] = -r_origin[1];
  430. modelorg[2] = -r_origin[2];
  431. VectorCopy( vec3_origin, r_entorigin );
  432. R_DrawBeam( currententity );
  433. }
  434. else
  435. {
  436. currentmodel = currententity->model;
  437. if (!currentmodel)
  438. {
  439. R_DrawNullModel();
  440. continue;
  441. }
  442. VectorCopy (currententity->origin, r_entorigin);
  443. VectorSubtract (r_origin, r_entorigin, modelorg);
  444. switch (currentmodel->type)
  445. {
  446. case mod_sprite:
  447. R_DrawSprite ();
  448. break;
  449. case mod_alias:
  450. R_AliasDrawModel ();
  451. break;
  452. default:
  453. break;
  454. }
  455. }
  456. }
  457. if ( !translucent_entities )
  458. return;
  459. for (i=0 ; i<r_newrefdef.num_entities ; i++)
  460. {
  461. currententity = &r_newrefdef.entities[i];
  462. if ( !( currententity->flags & RF_TRANSLUCENT ) )
  463. continue;
  464. if ( currententity->flags & RF_BEAM )
  465. {
  466. modelorg[0] = -r_origin[0];
  467. modelorg[1] = -r_origin[1];
  468. modelorg[2] = -r_origin[2];
  469. VectorCopy( vec3_origin, r_entorigin );
  470. R_DrawBeam( currententity );
  471. }
  472. else
  473. {
  474. currentmodel = currententity->model;
  475. if (!currentmodel)
  476. {
  477. R_DrawNullModel();
  478. continue;
  479. }
  480. VectorCopy (currententity->origin, r_entorigin);
  481. VectorSubtract (r_origin, r_entorigin, modelorg);
  482. switch (currentmodel->type)
  483. {
  484. case mod_sprite:
  485. R_DrawSprite ();
  486. break;
  487. case mod_alias:
  488. R_AliasDrawModel ();
  489. break;
  490. default:
  491. break;
  492. }
  493. }
  494. }
  495. }
  496. /*
  497. =============
  498. R_BmodelCheckBBox
  499. =============
  500. */
  501. int R_BmodelCheckBBox (float *minmaxs)
  502. {
  503. int i, *pindex, clipflags;
  504. vec3_t acceptpt, rejectpt;
  505. float d;
  506. clipflags = 0;
  507. for (i=0 ; i<4 ; i++)
  508. {
  509. // generate accept and reject points
  510. // FIXME: do with fast look-ups or integer tests based on the sign bit
  511. // of the floating point values
  512. pindex = pfrustum_indexes[i];
  513. rejectpt[0] = minmaxs[pindex[0]];
  514. rejectpt[1] = minmaxs[pindex[1]];
  515. rejectpt[2] = minmaxs[pindex[2]];
  516. d = DotProduct (rejectpt, view_clipplanes[i].normal);
  517. d -= view_clipplanes[i].dist;
  518. if (d <= 0)
  519. return BMODEL_FULLY_CLIPPED;
  520. acceptpt[0] = minmaxs[pindex[3+0]];
  521. acceptpt[1] = minmaxs[pindex[3+1]];
  522. acceptpt[2] = minmaxs[pindex[3+2]];
  523. d = DotProduct (acceptpt, view_clipplanes[i].normal);
  524. d -= view_clipplanes[i].dist;
  525. if (d <= 0)
  526. clipflags |= (1<<i);
  527. }
  528. return clipflags;
  529. }
  530. /*
  531. ===================
  532. R_FindTopnode
  533. Find the first node that splits the given box
  534. ===================
  535. */
  536. mnode_t *R_FindTopnode (vec3_t mins, vec3_t maxs)
  537. {
  538. mplane_t *splitplane;
  539. int sides;
  540. mnode_t *node;
  541. node = r_worldmodel->nodes;
  542. while (1)
  543. {
  544. if (node->visframe != r_visframecount)
  545. return NULL; // not visible at all
  546. if (node->contents != CONTENTS_NODE)
  547. {
  548. if (node->contents != CONTENTS_SOLID)
  549. return node; // we've reached a non-solid leaf, so it's
  550. // visible and not BSP clipped
  551. return NULL; // in solid, so not visible
  552. }
  553. splitplane = node->plane;
  554. sides = BOX_ON_PLANE_SIDE(mins, maxs, (cplane_t *)splitplane);
  555. if (sides == 3)
  556. return node; // this is the splitter
  557. // not split yet; recurse down the contacted side
  558. if (sides & 1)
  559. node = node->children[0];
  560. else
  561. node = node->children[1];
  562. }
  563. }
  564. /*
  565. =============
  566. RotatedBBox
  567. Returns an axially aligned box that contains the input box at the given rotation
  568. =============
  569. */
  570. void RotatedBBox (vec3_t mins, vec3_t maxs, vec3_t angles, vec3_t tmins, vec3_t tmaxs)
  571. {
  572. vec3_t tmp, v;
  573. int i, j;
  574. vec3_t forward, right, up;
  575. if (!angles[0] && !angles[1] && !angles[2])
  576. {
  577. VectorCopy (mins, tmins);
  578. VectorCopy (maxs, tmaxs);
  579. return;
  580. }
  581. for (i=0 ; i<3 ; i++)
  582. {
  583. tmins[i] = 99999;
  584. tmaxs[i] = -99999;
  585. }
  586. AngleVectors (angles, forward, right, up);
  587. for ( i = 0; i < 8; i++ )
  588. {
  589. if ( i & 1 )
  590. tmp[0] = mins[0];
  591. else
  592. tmp[0] = maxs[0];
  593. if ( i & 2 )
  594. tmp[1] = mins[1];
  595. else
  596. tmp[1] = maxs[1];
  597. if ( i & 4 )
  598. tmp[2] = mins[2];
  599. else
  600. tmp[2] = maxs[2];
  601. VectorScale (forward, tmp[0], v);
  602. VectorMA (v, -tmp[1], right, v);
  603. VectorMA (v, tmp[2], up, v);
  604. for (j=0 ; j<3 ; j++)
  605. {
  606. if (v[j] < tmins[j])
  607. tmins[j] = v[j];
  608. if (v[j] > tmaxs[j])
  609. tmaxs[j] = v[j];
  610. }
  611. }
  612. }
  613. /*
  614. =============
  615. R_DrawBEntitiesOnList
  616. =============
  617. */
  618. void R_DrawBEntitiesOnList (void)
  619. {
  620. int i, clipflags;
  621. vec3_t oldorigin;
  622. vec3_t mins, maxs;
  623. float minmaxs[6];
  624. mnode_t *topnode;
  625. if (!r_drawentities->value)
  626. return;
  627. VectorCopy (modelorg, oldorigin);
  628. insubmodel = true;
  629. r_dlightframecount = r_framecount;
  630. for (i=0 ; i<r_newrefdef.num_entities ; i++)
  631. {
  632. currententity = &r_newrefdef.entities[i];
  633. currentmodel = currententity->model;
  634. if (!currentmodel)
  635. continue;
  636. if (currentmodel->nummodelsurfaces == 0)
  637. continue; // clip brush only
  638. if ( currententity->flags & RF_BEAM )
  639. continue;
  640. if (currentmodel->type != mod_brush)
  641. continue;
  642. // see if the bounding box lets us trivially reject, also sets
  643. // trivial accept status
  644. RotatedBBox (currentmodel->mins, currentmodel->maxs,
  645. currententity->angles, mins, maxs);
  646. VectorAdd (mins, currententity->origin, minmaxs);
  647. VectorAdd (maxs, currententity->origin, (minmaxs+3));
  648. clipflags = R_BmodelCheckBBox (minmaxs);
  649. if (clipflags == BMODEL_FULLY_CLIPPED)
  650. continue; // off the edge of the screen
  651. topnode = R_FindTopnode (minmaxs, minmaxs+3);
  652. if (!topnode)
  653. continue; // no part in a visible leaf
  654. VectorCopy (currententity->origin, r_entorigin);
  655. VectorSubtract (r_origin, r_entorigin, modelorg);
  656. r_pcurrentvertbase = currentmodel->vertexes;
  657. // FIXME: stop transforming twice
  658. R_RotateBmodel ();
  659. // calculate dynamic lighting for bmodel
  660. R_PushDlights (currentmodel);
  661. if (topnode->contents == CONTENTS_NODE)
  662. {
  663. // not a leaf; has to be clipped to the world BSP
  664. r_clipflags = clipflags;
  665. R_DrawSolidClippedSubmodelPolygons (currentmodel, topnode);
  666. }
  667. else
  668. {
  669. // falls entirely in one leaf, so we just put all the
  670. // edges in the edge list and let 1/z sorting handle
  671. // drawing order
  672. R_DrawSubmodelPolygons (currentmodel, clipflags, topnode);
  673. }
  674. // put back world rotation and frustum clipping
  675. // FIXME: R_RotateBmodel should just work off base_vxx
  676. VectorCopy (base_vpn, vpn);
  677. VectorCopy (base_vup, vup);
  678. VectorCopy (base_vright, vright);
  679. VectorCopy (oldorigin, modelorg);
  680. R_TransformFrustum ();
  681. }
  682. insubmodel = false;
  683. }
  684. /*
  685. ================
  686. R_EdgeDrawing
  687. ================
  688. */
  689. void R_EdgeDrawing (void)
  690. {
  691. edge_t ledges[NUMSTACKEDGES +
  692. ((CACHE_SIZE - 1) / sizeof(edge_t)) + 1];
  693. surf_t lsurfs[NUMSTACKSURFACES +
  694. ((CACHE_SIZE - 1) / sizeof(surf_t)) + 1];
  695. if ( r_newrefdef.rdflags & RDF_NOWORLDMODEL )
  696. return;
  697. if (auxedges)
  698. {
  699. r_edges = auxedges;
  700. }
  701. else
  702. {
  703. r_edges = (edge_t *)
  704. (((long)&ledges[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1));
  705. }
  706. if (r_surfsonstack)
  707. {
  708. surfaces = (surf_t *)
  709. (((long)&lsurfs[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1));
  710. surf_max = &surfaces[r_cnumsurfs];
  711. // surface 0 doesn't really exist; it's just a dummy because index 0
  712. // is used to indicate no edge attached to surface
  713. surfaces--;
  714. R_SurfacePatch ();
  715. }
  716. R_BeginEdgeFrame ();
  717. if (r_dspeeds->value)
  718. {
  719. rw_time1 = Sys_Milliseconds ();
  720. }
  721. R_RenderWorld ();
  722. if (r_dspeeds->value)
  723. {
  724. rw_time2 = Sys_Milliseconds ();
  725. db_time1 = rw_time2;
  726. }
  727. R_DrawBEntitiesOnList ();
  728. if (r_dspeeds->value)
  729. {
  730. db_time2 = Sys_Milliseconds ();
  731. se_time1 = db_time2;
  732. }
  733. R_ScanEdges ();
  734. }
  735. //=======================================================================
  736. /*
  737. =============
  738. R_CalcPalette
  739. =============
  740. */
  741. void R_CalcPalette (void)
  742. {
  743. static qboolean modified;
  744. byte palette[256][4], *in, *out;
  745. int i, j;
  746. float alpha, one_minus_alpha;
  747. vec3_t premult;
  748. int v;
  749. alpha = r_newrefdef.blend[3];
  750. if (alpha <= 0)
  751. {
  752. if (modified)
  753. { // set back to default
  754. modified = false;
  755. R_GammaCorrectAndSetPalette( ( const unsigned char * ) d_8to24table );
  756. return;
  757. }
  758. return;
  759. }
  760. modified = true;
  761. if (alpha > 1)
  762. alpha = 1;
  763. premult[0] = r_newrefdef.blend[0]*alpha*255;
  764. premult[1] = r_newrefdef.blend[1]*alpha*255;
  765. premult[2] = r_newrefdef.blend[2]*alpha*255;
  766. one_minus_alpha = (1.0 - alpha);
  767. in = (byte *)d_8to24table;
  768. out = palette[0];
  769. for (i=0 ; i<256 ; i++, in+=4, out+=4)
  770. {
  771. for (j=0 ; j<3 ; j++)
  772. {
  773. v = premult[j] + one_minus_alpha * in[j];
  774. if (v > 255)
  775. v = 255;
  776. out[j] = v;
  777. }
  778. out[3] = 255;
  779. }
  780. R_GammaCorrectAndSetPalette( ( const unsigned char * ) palette[0] );
  781. // SWimp_SetPalette( palette[0] );
  782. }
  783. //=======================================================================
  784. void R_SetLightLevel (void)
  785. {
  786. vec3_t light;
  787. if ((r_newrefdef.rdflags & RDF_NOWORLDMODEL) || (!r_drawentities->value) || (!currententity))
  788. {
  789. r_lightlevel->value = 150.0;
  790. return;
  791. }
  792. // save off light value for server to look at (BIG HACK!)
  793. R_LightPoint (r_newrefdef.vieworg, light);
  794. r_lightlevel->value = 150.0 * light[0];
  795. }
  796. /*
  797. @@@@@@@@@@@@@@@@
  798. R_RenderFrame
  799. @@@@@@@@@@@@@@@@
  800. */
  801. void R_RenderFrame (refdef_t *fd)
  802. {
  803. r_newrefdef = *fd;
  804. if (!r_worldmodel && !( r_newrefdef.rdflags & RDF_NOWORLDMODEL ) )
  805. ri.Sys_Error (ERR_FATAL,"R_RenderView: NULL worldmodel");
  806. VectorCopy (fd->vieworg, r_refdef.vieworg);
  807. VectorCopy (fd->viewangles, r_refdef.viewangles);
  808. if (r_speeds->value || r_dspeeds->value)
  809. r_time1 = Sys_Milliseconds ();
  810. R_SetupFrame ();
  811. R_MarkLeaves (); // done here so we know if we're in water
  812. R_PushDlights (r_worldmodel);
  813. R_EdgeDrawing ();
  814. if (r_dspeeds->value)
  815. {
  816. se_time2 = Sys_Milliseconds ();
  817. de_time1 = se_time2;
  818. }
  819. R_DrawEntitiesOnList ();
  820. if (r_dspeeds->value)
  821. {
  822. de_time2 = Sys_Milliseconds ();
  823. dp_time1 = Sys_Milliseconds ();
  824. }
  825. R_DrawParticles ();
  826. if (r_dspeeds->value)
  827. dp_time2 = Sys_Milliseconds ();
  828. R_DrawAlphaSurfaces();
  829. R_SetLightLevel ();
  830. if (r_dowarp)
  831. D_WarpScreen ();
  832. if (r_dspeeds->value)
  833. da_time1 = Sys_Milliseconds ();
  834. if (r_dspeeds->value)
  835. da_time2 = Sys_Milliseconds ();
  836. R_CalcPalette ();
  837. if (sw_aliasstats->value)
  838. R_PrintAliasStats ();
  839. if (r_speeds->value)
  840. R_PrintTimes ();
  841. if (r_dspeeds->value)
  842. R_PrintDSpeeds ();
  843. if (sw_reportsurfout->value && r_outofsurfaces)
  844. ri.Con_Printf (PRINT_ALL,"Short %d surfaces\n", r_outofsurfaces);
  845. if (sw_reportedgeout->value && r_outofedges)
  846. ri.Con_Printf (PRINT_ALL,"Short roughly %d edges\n", r_outofedges * 2 / 3);
  847. }
  848. /*
  849. ** R_InitGraphics
  850. */
  851. void R_InitGraphics( int width, int height )
  852. {
  853. vid.width = width;
  854. vid.height = height;
  855. // free z buffer
  856. if ( d_pzbuffer )
  857. {
  858. free( d_pzbuffer );
  859. d_pzbuffer = NULL;
  860. }
  861. // free surface cache
  862. if ( sc_base )
  863. {
  864. D_FlushCaches ();
  865. free( sc_base );
  866. sc_base = NULL;
  867. }
  868. d_pzbuffer = malloc(vid.width*vid.height*2);
  869. R_InitCaches ();
  870. R_GammaCorrectAndSetPalette( ( const unsigned char *) d_8to24table );
  871. }
  872. /*
  873. ** R_BeginFrame
  874. */
  875. void R_BeginFrame( float camera_separation )
  876. {
  877. extern void Draw_BuildGammaTable( void );
  878. /*
  879. ** rebuild the gamma correction palette if necessary
  880. */
  881. if ( vid_gamma->modified )
  882. {
  883. Draw_BuildGammaTable();
  884. R_GammaCorrectAndSetPalette( ( const unsigned char * ) d_8to24table );
  885. vid_gamma->modified = false;
  886. }
  887. while ( sw_mode->modified || vid_fullscreen->modified )
  888. {
  889. rserr_t err;
  890. /*
  891. ** if this returns rserr_invalid_fullscreen then it set the mode but not as a
  892. ** fullscreen mode, e.g. 320x200 on a system that doesn't support that res
  893. */
  894. if ( ( err = SWimp_SetMode( &vid.width, &vid.height, sw_mode->value, vid_fullscreen->value ) ) == rserr_ok )
  895. {
  896. R_InitGraphics( vid.width, vid.height );
  897. sw_state.prev_mode = sw_mode->value;
  898. vid_fullscreen->modified = false;
  899. sw_mode->modified = false;
  900. }
  901. else
  902. {
  903. if ( err == rserr_invalid_mode )
  904. {
  905. ri.Cvar_SetValue( "sw_mode", sw_state.prev_mode );
  906. ri.Con_Printf( PRINT_ALL, "ref_soft::R_BeginFrame() - could not set mode\n" );
  907. }
  908. else if ( err == rserr_invalid_fullscreen )
  909. {
  910. R_InitGraphics( vid.width, vid.height );
  911. ri.Cvar_SetValue( "vid_fullscreen", 0);
  912. ri.Con_Printf( PRINT_ALL, "ref_soft::R_BeginFrame() - fullscreen unavailable in this mode\n" );
  913. sw_state.prev_mode = sw_mode->value;
  914. // vid_fullscreen->modified = false;
  915. // sw_mode->modified = false;
  916. }
  917. else
  918. {
  919. ri.Sys_Error( ERR_FATAL, "ref_soft::R_BeginFrame() - catastrophic mode change failure\n" );
  920. }
  921. }
  922. }
  923. }
  924. /*
  925. ** R_GammaCorrectAndSetPalette
  926. */
  927. void R_GammaCorrectAndSetPalette( const unsigned char *palette )
  928. {
  929. int i;
  930. for ( i = 0; i < 256; i++ )
  931. {
  932. sw_state.currentpalette[i*4+0] = sw_state.gammatable[palette[i*4+0]];
  933. sw_state.currentpalette[i*4+1] = sw_state.gammatable[palette[i*4+1]];
  934. sw_state.currentpalette[i*4+2] = sw_state.gammatable[palette[i*4+2]];
  935. }
  936. SWimp_SetPalette( sw_state.currentpalette );
  937. }
  938. /*
  939. ** R_CinematicSetPalette
  940. */
  941. void R_CinematicSetPalette( const unsigned char *palette )
  942. {
  943. byte palette32[1024];
  944. int i, j, w;
  945. int *d;
  946. // clear screen to black to avoid any palette flash
  947. w = abs(vid.rowbytes)>>2; // stupid negative pitch win32 stuff...
  948. for (i=0 ; i<vid.height ; i++, d+=w)
  949. {
  950. d = (int *)(vid.buffer + i*vid.rowbytes);
  951. for (j=0 ; j<w ; j++)
  952. d[j] = 0;
  953. }
  954. // flush it to the screen
  955. SWimp_EndFrame ();
  956. if ( palette )
  957. {
  958. for ( i = 0; i < 256; i++ )
  959. {
  960. palette32[i*4+0] = palette[i*3+0];
  961. palette32[i*4+1] = palette[i*3+1];
  962. palette32[i*4+2] = palette[i*3+2];
  963. palette32[i*4+3] = 0xFF;
  964. }
  965. R_GammaCorrectAndSetPalette( palette32 );
  966. }
  967. else
  968. {
  969. R_GammaCorrectAndSetPalette( ( const unsigned char * ) d_8to24table );
  970. }
  971. }
  972. /*
  973. ================
  974. Draw_BuildGammaTable
  975. ================
  976. */
  977. void Draw_BuildGammaTable (void)
  978. {
  979. int i, inf;
  980. float g;
  981. g = vid_gamma->value;
  982. if (g == 1.0)
  983. {
  984. for (i=0 ; i<256 ; i++)
  985. sw_state.gammatable[i] = i;
  986. return;
  987. }
  988. for (i=0 ; i<256 ; i++)
  989. {
  990. inf = 255 * pow ( (i+0.5)/255.5 , g ) + 0.5;
  991. if (inf < 0)
  992. inf = 0;
  993. if (inf > 255)
  994. inf = 255;
  995. sw_state.gammatable[i] = inf;
  996. }
  997. }
  998. /*
  999. ** R_DrawBeam
  1000. */
  1001. void R_DrawBeam( entity_t *e )
  1002. {
  1003. #define NUM_BEAM_SEGS 6
  1004. int i;
  1005. vec3_t perpvec;
  1006. vec3_t direction, normalized_direction;
  1007. vec3_t start_points[NUM_BEAM_SEGS], end_points[NUM_BEAM_SEGS];
  1008. vec3_t oldorigin, origin;
  1009. oldorigin[0] = e->oldorigin[0];
  1010. oldorigin[1] = e->oldorigin[1];
  1011. oldorigin[2] = e->oldorigin[2];
  1012. origin[0] = e->origin[0];
  1013. origin[1] = e->origin[1];
  1014. origin[2] = e->origin[2];
  1015. normalized_direction[0] = direction[0] = oldorigin[0] - origin[0];
  1016. normalized_direction[1] = direction[1] = oldorigin[1] - origin[1];
  1017. normalized_direction[2] = direction[2] = oldorigin[2] - origin[2];
  1018. if ( VectorNormalize( normalized_direction ) == 0 )
  1019. return;
  1020. PerpendicularVector( perpvec, normalized_direction );
  1021. VectorScale( perpvec, e->frame / 2, perpvec );
  1022. for ( i = 0; i < NUM_BEAM_SEGS; i++ )
  1023. {
  1024. RotatePointAroundVector( start_points[i], normalized_direction, perpvec, (360.0/NUM_BEAM_SEGS)*i );
  1025. VectorAdd( start_points[i], origin, start_points[i] );
  1026. VectorAdd( start_points[i], direction, end_points[i] );
  1027. }
  1028. for ( i = 0; i < NUM_BEAM_SEGS; i++ )
  1029. {
  1030. R_IMFlatShadedQuad( start_points[i],
  1031. end_points[i],
  1032. end_points[(i+1)%NUM_BEAM_SEGS],
  1033. start_points[(i+1)%NUM_BEAM_SEGS],
  1034. e->skinnum & 0xFF,
  1035. e->alpha );
  1036. }
  1037. }
  1038. //===================================================================
  1039. /*
  1040. ============
  1041. R_SetSky
  1042. ============
  1043. */
  1044. // 3dstudio environment map names
  1045. char *suf[6] = {"rt", "bk", "lf", "ft", "up", "dn"};
  1046. int r_skysideimage[6] = {5, 2, 4, 1, 0, 3};
  1047. extern mtexinfo_t r_skytexinfo[6];
  1048. void R_SetSky (char *name, float rotate, vec3_t axis)
  1049. {
  1050. int i;
  1051. char pathname[MAX_QPATH];
  1052. strncpy (skyname, name, sizeof(skyname)-1);
  1053. skyrotate = rotate;
  1054. VectorCopy (axis, skyaxis);
  1055. for (i=0 ; i<6 ; i++)
  1056. {
  1057. Com_sprintf (pathname, sizeof(pathname), "env/%s%s.pcx", skyname, suf[r_skysideimage[i]]);
  1058. r_skytexinfo[i].image = R_FindImage (pathname, it_sky);
  1059. }
  1060. }
  1061. /*
  1062. ===============
  1063. Draw_GetPalette
  1064. ===============
  1065. */
  1066. void Draw_GetPalette (void)
  1067. {
  1068. byte *pal, *out;
  1069. int i;
  1070. int r, g, b;
  1071. // get the palette and colormap
  1072. LoadPCX ("pics/colormap.pcx", &vid.colormap, &pal, NULL, NULL);
  1073. if (!vid.colormap)
  1074. ri.Sys_Error (ERR_FATAL, "Couldn't load pics/colormap.pcx");
  1075. vid.alphamap = vid.colormap + 64*256;
  1076. out = (byte *)d_8to24table;
  1077. for (i=0 ; i<256 ; i++, out+=4)
  1078. {
  1079. r = pal[i*3+0];
  1080. g = pal[i*3+1];
  1081. b = pal[i*3+2];
  1082. out[0] = r;
  1083. out[1] = g;
  1084. out[2] = b;
  1085. }
  1086. free (pal);
  1087. }
  1088. struct image_s *R_RegisterSkin (char *name);
  1089. /*
  1090. @@@@@@@@@@@@@@@@@@@@@
  1091. GetRefAPI
  1092. @@@@@@@@@@@@@@@@@@@@@
  1093. */
  1094. refexport_t GetRefAPI (refimport_t rimp)
  1095. {
  1096. refexport_t re;
  1097. ri = rimp;
  1098. re.api_version = API_VERSION;
  1099. re.BeginRegistration = R_BeginRegistration;
  1100. re.RegisterModel = R_RegisterModel;
  1101. re.RegisterSkin = R_RegisterSkin;
  1102. re.RegisterPic = Draw_FindPic;
  1103. re.SetSky = R_SetSky;
  1104. re.EndRegistration = R_EndRegistration;
  1105. re.RenderFrame = R_RenderFrame;
  1106. re.DrawGetPicSize = Draw_GetPicSize;
  1107. re.DrawPic = Draw_Pic;
  1108. re.DrawStretchPic = Draw_StretchPic;
  1109. re.DrawChar = Draw_Char;
  1110. re.DrawTileClear = Draw_TileClear;
  1111. re.DrawFill = Draw_Fill;
  1112. re.DrawFadeScreen= Draw_FadeScreen;
  1113. re.DrawStretchRaw = Draw_StretchRaw;
  1114. re.Init = R_Init;
  1115. re.Shutdown = R_Shutdown;
  1116. re.CinematicSetPalette = R_CinematicSetPalette;
  1117. re.BeginFrame = R_BeginFrame;
  1118. re.EndFrame = SWimp_EndFrame;
  1119. re.AppActivate = SWimp_AppActivate;
  1120. Swap_Init ();
  1121. return re;
  1122. }
  1123. #ifndef REF_HARD_LINKED
  1124. // this is only here so the functions in q_shared.c and q_shwin.c can link
  1125. void Sys_Error (char *error, ...)
  1126. {
  1127. va_list argptr;
  1128. char text[1024];
  1129. va_start (argptr, error);
  1130. vsprintf (text, error, argptr);
  1131. va_end (argptr);
  1132. ri.Sys_Error (ERR_FATAL, "%s", text);
  1133. }
  1134. void Com_Printf (char *fmt, ...)
  1135. {
  1136. va_list argptr;
  1137. char text[1024];
  1138. va_start (argptr, fmt);
  1139. vsprintf (text, fmt, argptr);
  1140. va_end (argptr);
  1141. ri.Con_Printf (PRINT_ALL, "%s", text);
  1142. }
  1143. #endif