Quake II RTX doxygen  1.0 dev
main.c
Go to the documentation of this file.
1 /*
2 Copyright (C) 1997-2001 Id Software, Inc.
3 
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8 
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13 
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation, Inc.,
16 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18 // r_main.c
19 
20 #include "sw.h"
21 
23 
24 refcfg_t r_config;
25 
26 entity_t r_worldentity;
27 
28 refdef_t r_newrefdef;
29 model_t *currentmodel;
30 
31 bsp_t *r_worldmodel;
32 
34 
35 float r_time1;
39 
40 qboolean r_dowarp;
41 
42 int c_surf;
45 
46 //
47 // view origin
48 //
49 vec3_t vup, base_vup;
50 vec3_t vpn, base_vpn;
52 vec3_t r_origin;
53 
54 //
55 // screen size info
56 //
58 
59 cplane_t screenedge[4];
60 
61 //
62 // refresh flags
63 //
64 int r_framecount = 1; // so frame counts initialized to 0 don't match
69 
71 int r_frustum_indexes[4 * 6];
72 
73 mleaf_t *r_viewleaf;
75 
76 cvar_t *sw_aliasstats;
77 cvar_t *sw_clearcolor;
78 cvar_t *sw_drawflat;
79 cvar_t *sw_draworder;
80 cvar_t *sw_maxedges;
81 cvar_t *sw_maxsurfs;
85 cvar_t *sw_waterwarp;
86 cvar_t *sw_dynamic;
87 cvar_t *sw_modulate;
88 cvar_t *sw_lockpvs;
89 
90 //Start Added by Lewey
91 // These flags allow you to turn SIRDS on and
92 // off from the console.
93 cvar_t *sw_drawsird;
94 //End Added by Lewey
95 
96 cvar_t *r_drawworld;
98 cvar_t *r_fullbright;
99 cvar_t *r_lerpmodels;
100 cvar_t *r_novis;
101 
102 cvar_t *r_speeds;
103 
104 cvar_t *vid_gamma;
105 
106 // all global and static refresh variables are collected in a contiguous block
107 // to avoid cache conflicts.
108 
109 //-------------------------------------------------------
110 // global refresh variables
111 //-------------------------------------------------------
112 
113 // FIXME: make into one big structure, like cl or sv
114 // FIXME: do separately for refresh engine and driver
115 
119 
121 
124 
127 short *d_pzbuffer;
132 
133 int sintable[CYCLE * 2];
135 int blanktable[CYCLE * 2];
136 
137 /*
138 ================
139 R_InitTurb
140 ================
141 */
142 void R_InitTurb(void)
143 {
144  int i;
145 
146  for (i = 0; i < CYCLE * 2; i++) {
147  sintable[i] = AMP + sin(i * M_PI * 2 / CYCLE) * AMP;
148  intsintable[i] = AMP2 + sin(i * M_PI * 2 / CYCLE) * AMP2; // AMP2, not 20
149  blanktable[i] = 0;
150  }
151 }
152 
153 static void R_Register(void)
154 {
155  sw_aliasstats = Cvar_Get("sw_polymodelstats", "0", 0);
156  sw_clearcolor = Cvar_Get("sw_clearcolor", "2", 0);
157  sw_drawflat = Cvar_Get("sw_drawflat", "0", CVAR_CHEAT);
158  sw_draworder = Cvar_Get("sw_draworder", "0", CVAR_CHEAT);
159  sw_maxedges = Cvar_Get("sw_maxedges", STRINGIFY(NUMSTACKEDGES), 0);
160  sw_maxsurfs = Cvar_Get("sw_maxsurfs", STRINGIFY(NUMSTACKSURFACES), 0);
161  sw_mipcap = Cvar_Get("sw_mipcap", "0", 0);
162  sw_mipscale = Cvar_Get("sw_mipscale", "1", 0);
163  sw_reportedgeout = Cvar_Get("sw_reportedgeout", "0", 0);
164  sw_reportsurfout = Cvar_Get("sw_reportsurfout", "0", 0);
165  sw_waterwarp = Cvar_Get("sw_waterwarp", "1", 0);
166  sw_dynamic = Cvar_Get("sw_dynamic", "1", 0);
167  sw_modulate = Cvar_Get("sw_modulate", "1", 0);
168  sw_lockpvs = Cvar_Get("sw_lockpvs", "0", 0);
169 
170  //Start Added by Lewey
171  sw_drawsird = Cvar_Get("sw_drawsird", "0", 0);
172  //End Added by Lewey
173 
174  r_speeds = Cvar_Get("r_speeds", "0", 0);
175  r_fullbright = Cvar_Get("r_fullbright", "0", CVAR_CHEAT);
176  r_drawentities = Cvar_Get("r_drawentities", "1", 0);
177  r_drawworld = Cvar_Get("r_drawworld", "1", CVAR_CHEAT);
178  r_lerpmodels = Cvar_Get("r_lerpmodels", "1", 0);
179  r_novis = Cvar_Get("r_novis", "0", 0);
180 
181  vid_gamma = Cvar_Get("vid_gamma", "1.0", CVAR_ARCHIVE | CVAR_FILES);
182 
183  Cmd_AddCommand("scdump", D_SCDump_f);
184 }
185 
186 static void R_UnRegister(void)
187 {
188  Cmd_RemoveCommand("scdump");
189 }
190 
191 void R_ModeChanged(int width, int height, int flags, int rowbytes, void *pixels)
192 {
195  vid.buffer = pixels;
196  vid.rowbytes = rowbytes;
197 
198  if (width > MAXWIDTH)
199  vid.buffer += (width - MAXWIDTH) * VID_BYTES / 2;
200 
201  if (height > MAXHEIGHT)
202  vid.buffer += (height - MAXHEIGHT) * rowbytes / 2;
203 
204  r_config.width = vid.width;
205  r_config.height = vid.height;
206  r_config.flags = flags;
207 
208  R_SetClipRect(NULL);
209 
210  sw_surfcacheoverride = Cvar_Get("sw_surfcacheoverride", "0", 0);
211 
212  D_FlushCaches();
213 
214  if (d_pzbuffer) {
216  d_pzbuffer = NULL;
217  }
218 
219  // free surface cache
220  R_FreeCaches();
221 
222  d_pzbuffer = R_Mallocz(vid.width * vid.height * 2);
223  d_zrowbytes = vid.width * 2;
224  d_zwidth = vid.width;
225 
226  R_InitCaches();
227 }
228 
229 /*
230 ===============
231 R_Init
232 ===============
233 */
234 qboolean R_Init(qboolean total)
235 {
236  Com_DPrintf("R_Init( %i )\n", total);
237 
238  if (!total) {
239  R_InitImages();
240  R_InitDraw();
241  MOD_Init();
242  return qtrue;
243  }
244 
245  Com_DPrintf("ref_soft " VERSION ", " __DATE__ "\n");
246 
247  // create the window
248  if (!VID_Init())
249  return qfalse;
250 
251  R_Register();
252 
253  IMG_Init();
254 
255  MOD_Init();
256 
257  R_InitImages();
258 
259  R_InitSkyBox();
260 
261  view_clipplanes[0].leftedge = qtrue;
262  view_clipplanes[1].rightedge = qtrue;
265  view_clipplanes[3].leftedge = qfalse;
268  view_clipplanes[3].rightedge = qfalse;
269 
270  R_InitTurb();
271 
272  return qtrue;
273 }
274 
275 /*
276 ===============
277 R_Shutdown
278 ===============
279 */
280 void R_Shutdown(qboolean total)
281 {
282  Com_DPrintf("R_Shutdown( %i )\n", total);
283 
284  D_FlushCaches();
285 
286  MOD_Shutdown();
287 
289 
290  if (auxsurfaces) {
292  auxsurfaces = NULL;
293  }
294 
295  if (auxedges) {
296  Z_Free(auxedges);
297  auxedges = NULL;
298  }
299 
300  // free world model
301  if (r_worldmodel) {
303  r_worldmodel = NULL;
304  }
305 
306  if (!total) {
307  return;
308  }
309 
310  // free z buffer
311  if (d_pzbuffer) {
313  d_pzbuffer = NULL;
314  }
315 
316  // free surface cache
317  R_FreeCaches();
318 
319  R_UnRegister();
320 
321  IMG_Shutdown();
322 
323  VID_Shutdown();
324 }
325 
326 /*
327 ===============
328 R_NewMap
329 ===============
330 */
331 void R_NewMap(void)
332 {
333  r_viewcluster = -1;
334 
335  if (auxsurfaces) {
337  auxsurfaces = NULL;
338  }
339 
340  if (auxedges) {
341  Z_Free(auxedges);
342  auxedges = NULL;
343  }
344 
346 
348  surfaces = auxsurfaces = R_Mallocz(r_cnumsurfs * sizeof(surf_t));
351  // surface 0 doesn't really exist; it's just a dummy because index 0
352  // is used to indicate no edge attached to surface
353  surfaces--;
354  }
355 
356  r_maxedgesseen = 0;
357  r_maxsurfsseen = 0;
358 
360 
362  auxedges = R_Mallocz(r_numallocatededges * sizeof(edge_t));
363  }
364 }
365 
366 
367 /*
368 ===============
369 R_MarkLeaves
370 
371 Mark the leaves and nodes that are in the PVS for the current
372 cluster
373 ===============
374 */
375 static void R_MarkLeaves(void)
376 {
377  byte vis[VIS_MAX_BYTES];
378  mnode_t *node;
379  int i;
380  mleaf_t *leaf;
381  int cluster;
382 
383  if (r_oldviewcluster == r_viewcluster && !r_novis->integer &&
384  r_viewcluster != -1) {
385  return;
386  }
387 
388  // development aid to let you run around and see exactly where
389  // the pvs ends
390  if (sw_lockpvs->integer)
391  return;
392 
393  r_visframecount++;
395 
396  if (r_novis->integer || r_viewcluster == -1 || !r_worldmodel->vis) {
397  // mark everything
398  for (i = 0; i < r_worldmodel->numleafs; i++)
399  r_worldmodel->leafs[i].visframe = r_visframecount;
400  for (i = 0; i < r_worldmodel->numnodes; i++)
401  r_worldmodel->nodes[i].visframe = r_visframecount;
402  return;
403  }
404 
405  BSP_ClusterVis(r_worldmodel, vis, r_viewcluster, DVIS_PVS);
406 
407  for (i = 0, leaf = r_worldmodel->leafs; i < r_worldmodel->numleafs; i++, leaf++) {
408  cluster = leaf->cluster;
409  if (cluster == -1)
410  continue;
411  if (Q_IsBitSet(vis, cluster)) {
412  node = (mnode_t *)leaf;
413  do {
414  if (node->visframe == r_visframecount)
415  break;
416  node->visframe = r_visframecount;
417  node = node->parent;
418  } while (node);
419  }
420  }
421 
422 }
423 
424 /*
425 ** R_DrawNullModel
426 **
427 ** IMPLEMENT THIS!
428 */
429 static void R_DrawNullModel(void)
430 {
431 }
432 
433 static int R_DrawEntities(int translucent)
434 {
435  int i;
436  qboolean translucent_entities = 0;
437 
438  // all bmodels have already been drawn by the edge list
439  for (i = 0; i < r_newrefdef.num_entities; i++) {
440  currententity = &r_newrefdef.entities[i];
441 
442  if ((currententity->flags & RF_TRANSLUCENT) == translucent) {
443  translucent_entities++;
444  continue;
445  }
446 
447  if (currententity->flags & RF_BEAM) {
448  modelorg[0] = -r_origin[0];
449  modelorg[1] = -r_origin[1];
450  modelorg[2] = -r_origin[2];
451  VectorCopy(vec3_origin, r_entorigin);
453  } else {
454  if (currententity->model & 0x80000000) {
455  continue;
456  }
458  if (!currentmodel) {
459  R_DrawNullModel();
460  continue;
461  }
462  VectorCopy(currententity->origin, r_entorigin);
463  VectorSubtract(r_origin, r_entorigin, modelorg);
464 
465  switch (currentmodel->type) {
466  case MOD_ALIAS:
468  break;
469  case MOD_SPRITE:
470  R_DrawSprite();
471  break;
472  case MOD_EMPTY:
473  break;
474  default:
475  Com_Error(ERR_FATAL, "%s: bad model type", __func__);
476  }
477  }
478  }
479  return translucent_entities;
480 }
481 
482 /*
483 =============
484 R_DrawEntitiesOnList
485 =============
486 */
487 static void R_DrawEntitiesOnList(void)
488 {
489  int translucent_entities;
490 
491  if (!r_drawentities->integer)
492  return;
493 
494  translucent_entities = R_DrawEntities(RF_TRANSLUCENT);
495  if (translucent_entities) {
496  R_DrawEntities(0);
497  }
498 }
499 
500 
501 /*
502 =============
503 R_BmodelCheckBBox
504 =============
505 */
506 static int R_BmodelCheckBBox(float *minmaxs)
507 {
508  int i, *pindex, clipflags;
509  vec3_t acceptpt, rejectpt;
510  float d;
511 
512  clipflags = 0;
513 
514  for (i = 0; i < 4; i++) {
515  // generate accept and reject points
516  // FIXME: do with fast look-ups or integer tests based on the sign bit
517  // of the floating point values
518 
519  pindex = pfrustum_indexes[i];
520 
521  rejectpt[0] = minmaxs[pindex[0]];
522  rejectpt[1] = minmaxs[pindex[1]];
523  rejectpt[2] = minmaxs[pindex[2]];
524 
525  d = DotProduct(rejectpt, view_clipplanes[i].normal);
526  d -= view_clipplanes[i].dist;
527 
528  if (d <= 0)
529  return BMODEL_FULLY_CLIPPED;
530 
531  acceptpt[0] = minmaxs[pindex[3 + 0]];
532  acceptpt[1] = minmaxs[pindex[3 + 1]];
533  acceptpt[2] = minmaxs[pindex[3 + 2]];
534 
535  d = DotProduct(acceptpt, view_clipplanes[i].normal);
536  d -= view_clipplanes[i].dist;
537 
538  if (d <= 0)
539  clipflags |= (1 << i);
540  }
541 
542  return clipflags;
543 }
544 
545 
546 /*
547 ===================
548 R_FindTopnode
549 
550 Find the first node that splits the given box
551 ===================
552 */
553 static mnode_t *R_FindTopnode(vec3_t mins, vec3_t maxs)
554 {
555  int sides;
556  mnode_t *node;
557 
558  node = r_worldmodel->nodes;
559 
560  while (node->visframe == r_visframecount) {
561  if (!node->plane) {
562  if (((mleaf_t *)node)->contents != CONTENTS_SOLID)
563  return node; // we've reached a non-solid leaf, so it's
564  // visible and not BSP clipped
565  return NULL; // in solid, so not visible
566  }
567 
568  sides = BoxOnPlaneSideFast(mins, maxs, node->plane);
569 
570  if (sides == BOX_INTERSECTS)
571  return node; // this is the splitter
572 
573  // not split yet; recurse down the contacted side
574  if (sides & BOX_INFRONT)
575  node = node->children[0];
576  else
577  node = node->children[1];
578  }
579 
580  return NULL; // not visible at all
581 }
582 
583 
584 /*
585 =============
586 RotatedBBox
587 
588 Returns an axially aligned box that contains the input box at the given rotation
589 =============
590 */
591 static void RotatedBBox(vec3_t mins, vec3_t maxs, vec3_t angles,
592  vec3_t tmins, vec3_t tmaxs)
593 {
594  vec3_t tmp, v;
595  int i, j;
596  vec3_t forward, right, up;
597 
598  if (!angles[0] && !angles[1] && !angles[2]) {
599  VectorCopy(mins, tmins);
600  VectorCopy(maxs, tmaxs);
601  return;
602  }
603 
604  for (i = 0; i < 3; i++) {
605  tmins[i] = 99999;
606  tmaxs[i] = -99999;
607  }
608 
609  AngleVectors(angles, forward, right, up);
610 
611  for (i = 0; i < 8; i++) {
612  if (i & 1)
613  tmp[0] = mins[0];
614  else
615  tmp[0] = maxs[0];
616 
617  if (i & 2)
618  tmp[1] = mins[1];
619  else
620  tmp[1] = maxs[1];
621 
622  if (i & 4)
623  tmp[2] = mins[2];
624  else
625  tmp[2] = maxs[2];
626 
627 
628  VectorScale(forward, tmp[0], v);
629  VectorMA(v, -tmp[1], right, v);
630  VectorMA(v, tmp[2], up, v);
631 
632  for (j = 0; j < 3; j++) {
633  if (v[j] < tmins[j])
634  tmins[j] = v[j];
635  if (v[j] > tmaxs[j])
636  tmaxs[j] = v[j];
637  }
638  }
639 }
640 
641 /*
642 =============
643 R_DrawBEntitiesOnList
644 =============
645 */
646 static void R_DrawBEntitiesOnList(void)
647 {
648  int i, index, clipflags;
649  vec3_t oldorigin;
650  vec3_t mins, maxs;
651  float minmaxs[6];
652  mnode_t *topnode;
653  mmodel_t *model;
654 
655  if (!r_drawentities->integer)
656  return;
657 
658  VectorCopy(modelorg, oldorigin);
659  insubmodel = qtrue;
661 
662  for (i = 0; i < r_newrefdef.num_entities; i++) {
663  currententity = &r_newrefdef.entities[i];
664  index = currententity->model;
665  if (!(index & 0x80000000)) {
666  continue;
667  }
668  index = ~index;
669  if (index < 1 || index >= r_worldmodel->nummodels) {
670  Com_Error(ERR_DROP, "%s: inline model %d out of range",
671  __func__, index);
672  }
673  model = &r_worldmodel->models[index];
674  if (model->numfaces == 0)
675  continue; // clip brush only
676  if (currententity->flags & RF_BEAM)
677  continue;
678  // see if the bounding box lets us trivially reject, also sets
679  // trivial accept status
680  RotatedBBox(model->mins, model->maxs,
681  currententity->angles, mins, maxs);
682  VectorAdd(mins, currententity->origin, minmaxs);
683  VectorAdd(maxs, currententity->origin, (minmaxs + 3));
684 
685  clipflags = R_BmodelCheckBBox(minmaxs);
686  if (clipflags == BMODEL_FULLY_CLIPPED)
687  continue; // off the edge of the screen
688 
689  topnode = R_FindTopnode(minmaxs, minmaxs + 3);
690  if (!topnode)
691  continue; // no part in a visible leaf
692 
693  VectorCopy(currententity->origin, r_entorigin);
694  VectorSubtract(r_origin, r_entorigin, modelorg);
695 
696  // FIXME: stop transforming twice
697  R_RotateBmodel();
698 
699  // calculate dynamic lighting for bmodel
700  R_MarkLights(model->headnode);
701 
702  if (topnode->plane) {
703  // not a leaf; has to be clipped to the world BSP
704  r_clipflags = clipflags;
705  R_DrawSolidClippedSubmodelPolygons(model, topnode);
706  } else {
707  // falls entirely in one leaf, so we just put all the
708  // edges in the edge list and let 1/z sorting handle
709  // drawing order
710  R_DrawSubmodelPolygons(model, clipflags, topnode);
711  }
712 
713  // put back world rotation and frustum clipping
714  // FIXME: R_RotateBmodel should just work off base_vxx
715  VectorCopy(base_vpn, vpn);
716  VectorCopy(base_vup, vup);
717  VectorCopy(base_vright, vright);
718  VectorCopy(oldorigin, modelorg);
720  }
721 
722  insubmodel = qfalse;
723 }
724 
725 
726 /*
727 ================
728 R_EdgeDrawing
729 ================
730 */
731 static void R_EdgeDrawing(void)
732 {
733  edge_t ledges[NUMSTACKEDGES +
734  ((CACHE_SIZE - 1) / sizeof(edge_t)) + 1];
735  surf_t lsurfs[NUMSTACKSURFACES +
736  ((CACHE_SIZE - 1) / sizeof(surf_t)) + 1];
737 
738  if (r_newrefdef.rdflags & RDF_NOWORLDMODEL)
739  return;
740 
741  if (auxedges) {
742  r_edges = auxedges;
743  } else {
744  r_edges = (edge_t *)
745  (((uintptr_t)&ledges[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1));
746  }
747 
748  if (!auxsurfaces) {
749  surfaces = (surf_t *)
750  (((uintptr_t)&lsurfs[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1));
752  // surface 0 doesn't really exist; it's just a dummy because index 0
753  // is used to indicate no edge attached to surface
754  surfaces--;
755  }
756 
758 
759  R_RenderWorld();
760 
762 
763  R_ScanEdges();
764 }
765 
766 //=======================================================================
767 
768 byte *IMG_ReadPixels(int *width, int *height, int *rowbytes)
769 {
770  byte *pixels;
771  byte *src, *dst;
772  int x, y;
773 
774  pixels = FS_AllocTempMem(vid.width * vid.height * 3);
775 
776  src = vid.buffer + vid.rowbytes * (vid.height - 1);
777  dst = pixels;
778 
779  for (y = 0; y < vid.height; y++, src -= vid.rowbytes) {
780  for (x = 0; x < vid.width; x++) {
781  dst[0] = src[x * VID_BYTES + 2];
782  dst[1] = src[x * VID_BYTES + 1];
783  dst[2] = src[x * VID_BYTES + 0];
784  dst += 3;
785  }
786  }
787 
788  *width = vid.width;
789  *height = vid.height;
790  *rowbytes = vid.width * 3;
791 
792  return pixels;
793 }
794 
795 //=======================================================================
796 
797 /*
798 @@@@@@@@@@@@@@@@
799 R_RenderFrame
800 
801 @@@@@@@@@@@@@@@@
802 */
803 void R_RenderFrame(refdef_t *fd)
804 {
805  r_newrefdef = *fd;
806 
807  if (!r_worldmodel && !(r_newrefdef.rdflags & RDF_NOWORLDMODEL))
808  Com_Error(ERR_FATAL, "R_RenderView: NULL worldmodel");
809 
810  if (!sw_dynamic->integer)
811  r_newrefdef.num_dlights = 0;
812 
813  if (r_speeds->integer)
815 
816  R_SetupFrame();
817 
818  R_MarkLeaves(); // done here so we know if we're in water
819 
820  if (r_worldmodel)
821  R_MarkLights(r_worldmodel->nodes);
822 
823  R_EdgeDrawing();
824 
826 
827  R_DrawParticles();
828 
830 
831  //Start Replaced by Lewey
832  if (sw_drawsird->integer && !(r_newrefdef.rdflags & RDF_NOWORLDMODEL)) {
834  } else {
835  //don't do warp if we are doing SIRD because the warp
836  //would make the SIRD impossible to see.
837  if (r_dowarp)
838  D_WarpScreen();
839  }
840  //End Replaced by Lewey
841 
842  if (sw_aliasstats->integer)
844 
845  if (r_speeds->integer)
846  R_PrintTimes();
847 
848  if (sw_reportsurfout->integer && r_outofsurfaces)
849  Com_Printf("Short %d surfaces\n", r_outofsurfaces);
850 
851  if (sw_reportedgeout->integer && r_outofedges)
852  Com_Printf("Short roughly %d edges\n", r_outofedges * 2 / 3);
853 }
854 
855 /*
856 ** R_BeginFrame
857 */
858 void R_BeginFrame(void)
859 {
860  VID_BeginFrame();
861 }
862 
863 void R_EndFrame(void)
864 {
865  VID_EndFrame();
866 }
867 
868 /*
869 ** R_DrawBeam
870 */
871 void R_DrawBeam(entity_t *e)
872 {
873 #define NUM_BEAM_SEGS 6
874 
875  color_t color;
876  int i;
877 
878  vec3_t perpvec;
879  vec3_t direction, normalized_direction;
880  vec3_t start_points[NUM_BEAM_SEGS], end_points[NUM_BEAM_SEGS];
881  vec3_t oldorigin, origin;
882 
883  oldorigin[0] = e->oldorigin[0];
884  oldorigin[1] = e->oldorigin[1];
885  oldorigin[2] = e->oldorigin[2];
886 
887  origin[0] = e->origin[0];
888  origin[1] = e->origin[1];
889  origin[2] = e->origin[2];
890 
891  normalized_direction[0] = direction[0] = oldorigin[0] - origin[0];
892  normalized_direction[1] = direction[1] = oldorigin[1] - origin[1];
893  normalized_direction[2] = direction[2] = oldorigin[2] - origin[2];
894 
895  if (VectorNormalize(normalized_direction) == 0)
896  return;
897 
898  PerpendicularVector(perpvec, normalized_direction);
899  VectorScale(perpvec, e->frame / 2, perpvec);
900 
901  for (i = 0; i < NUM_BEAM_SEGS; i++) {
902  RotatePointAroundVector(start_points[i], normalized_direction,
903  perpvec, (360.0f / NUM_BEAM_SEGS) * i);
904  VectorAdd(start_points[i], origin, start_points[i]);
905  VectorAdd(start_points[i], direction, end_points[i]);
906  }
907 
908  if (e->skinnum == -1)
909  color.u32 = e->rgba.u32;
910  else
911  color.u32 = d_8to24table[e->skinnum & 0xFF];
912 
913  for (i = 0; i < NUM_BEAM_SEGS; i++) {
914  R_IMFlatShadedQuad(start_points[i],
915  end_points[i],
916  end_points[(i + 1) % NUM_BEAM_SEGS],
917  start_points[(i + 1) % NUM_BEAM_SEGS],
918  color,
919  e->alpha);
920  }
921 }
922 
923 void R_AddDecal(decal_t *d) {}
base_vright
vec3_t base_vright
Definition: main.c:51
IMG_ReadPixels
byte * IMG_ReadPixels(int *width, int *height, int *rowbytes)
Definition: main.c:768
d_viewbuffer
pixel_t * d_viewbuffer
Definition: main.c:125
R_ShutdownImages
void R_ShutdownImages(void)
Definition: image.c:180
r_dlightframecount
int r_dlightframecount
Definition: light.c:22
r_config
refcfg_t r_config
Definition: main.c:24
MAXWIDTH
#define MAXWIDTH
Definition: sw.h:58
r_origin
vec3_t r_origin
Definition: main.c:52
NUMSTACKSURFACES
#define NUMSTACKSURFACES
Definition: sw.h:81
MINSURFACES
#define MINSURFACES
Definition: sw.h:82
R_DrawParticles
void R_DrawParticles(void)
Definition: part.c:119
R_ScanEdges
void R_ScanEdges(void)
Definition: edge.c:556
r_newrefdef
refdef_t r_newrefdef
Definition: main.c:28
height
static int height
Definition: physical_sky.c:39
viddef_t::buffer
pixel_t * buffer
Definition: sw.h:124
d_sdivzstepv
float d_sdivzstepv
Definition: main.c:117
sw_maxsurfs
cvar_t * sw_maxsurfs
Definition: main.c:81
r_drawentities
cvar_t * r_drawentities
Definition: main.c:97
r_edges
edge_t * r_edges
Definition: edge.c:32
R_DrawNullModel
static void R_DrawNullModel(void)
Definition: main.c:429
RotatedBBox
static void RotatedBBox(vec3_t mins, vec3_t maxs, vec3_t angles, vec3_t tmins, vec3_t tmaxs)
Definition: main.c:591
MOD_ForHandle
model_t * MOD_ForHandle(qhandle_t h)
Definition: models.c:430
Cmd_AddCommand
void Cmd_AddCommand(const char *name, xcommand_t function)
Definition: cmd.c:1562
r_cnumsurfs
int r_cnumsurfs
Definition: main.c:43
R_InitImages
void R_InitImages(void)
Definition: image.c:164
Cvar_Get
cvar_t * Cvar_Get(const char *var_name, const char *var_value, int flags)
Definition: cvar.c:257
R_FindTopnode
static mnode_t * R_FindTopnode(vec3_t mins, vec3_t maxs)
Definition: main.c:553
BSP_ClusterVis
byte * BSP_ClusterVis(bsp_t *bsp, byte *mask, int cluster, int vis)
Definition: bsp.c:1339
MOD_Init
void MOD_Init(void)
Definition: models.c:450
base_vup
vec3_t base_vup
Definition: main.c:49
cacheblock
pixel_t * cacheblock
Definition: main.c:122
D_WarpScreen
void D_WarpScreen(void)
Definition: scan.c:32
R_Register
static void R_Register(void)
Definition: main.c:153
viddef_t::width
int width
Definition: sw.h:127
VID_EndFrame
void VID_EndFrame(void)
Definition: glimp.c:516
R_PrintAliasStats
void R_PrintAliasStats(void)
Definition: misc.c:58
r_frustum_indexes
int r_frustum_indexes[4 *6]
Definition: main.c:71
r_drawworld
cvar_t * r_drawworld
Definition: main.c:96
r_viewcluster
int r_viewcluster
Definition: main.c:74
D_SCDump_f
void D_SCDump_f(void)
Definition: surf.c:311
sw_surfcacheoverride
cvar_t * sw_surfcacheoverride
Definition: main.c:84
r_framecount
int r_framecount
Definition: main.c:64
BMODEL_FULLY_CLIPPED
#define BMODEL_FULLY_CLIPPED
Definition: sw.h:96
CYCLE
#define CYCLE
Definition: sw.h:74
d_screenrowbytes
int d_screenrowbytes
Definition: main.c:126
d_zrowbytes
int d_zrowbytes
Definition: main.c:128
viddef_t::height
int height
Definition: sw.h:128
r_refdef
oldrefdef_t r_refdef
Definition: main.c:57
d_zistepu
float d_zistepu
Definition: main.c:116
c_surf
int c_surf
Definition: main.c:42
d_8to24table
uint32_t d_8to24table[256]
Definition: images.c:654
R_NewMap
void R_NewMap(void)
Definition: main.c:331
R_Shutdown
void R_Shutdown(qboolean total)
Definition: main.c:280
AMP2
#define AMP2
Definition: sw.h:109
MAXSURFACES
#define MAXSURFACES
Definition: sw.h:83
R_DrawBeam
void R_DrawBeam(entity_t *e)
Definition: main.c:871
AMP
#define AMP
Definition: sw.h:108
R_EndFrame
void R_EndFrame(void)
Definition: main.c:863
MINEDGES
#define MINEDGES
Definition: sw.h:79
R_DrawEntities
static int R_DrawEntities(int translucent)
Definition: main.c:433
r_dowarp
qboolean r_dowarp
Definition: main.c:40
viddef_t
Definition: sw.h:123
r_viewleaf
mleaf_t * r_viewleaf
Definition: main.c:73
R_BeginEdgeFrame
void R_BeginEdgeFrame(void)
Definition: edge.c:80
sw_mipcap
cvar_t * sw_mipcap
Definition: misc.c:24
blanktable
int blanktable[CYCLE *2]
Definition: main.c:135
r_maxedgesseen
int r_maxedgesseen
Definition: main.c:43
vup
vec3_t vup
Definition: main.c:49
Sys_Milliseconds
unsigned Sys_Milliseconds(void)
Definition: system.c:644
sw_reportedgeout
cvar_t * sw_reportedgeout
Definition: main.c:82
R_AliasDrawModel
void R_AliasDrawModel(void)
Definition: alias.c:674
sw_draworder
cvar_t * sw_draworder
Definition: main.c:79
r_polycount
int r_polycount
Definition: main.c:66
R_DrawSprite
void R_DrawSprite(void)
Definition: poly.c:835
r_fullbright
cvar_t * r_fullbright
Definition: main.c:98
r_outofedges
int r_outofedges
Definition: main.c:38
vec3_origin
vec3_t vec3_origin
Definition: shared.c:21
width
static int width
Definition: physical_sky.c:38
R_DrawBEntitiesOnList
static void R_DrawBEntitiesOnList(void)
Definition: main.c:646
cachewidth
int cachewidth
Definition: main.c:123
currententity
entity_t * currententity
Definition: bsp.c:26
R_UnRegister
static void R_UnRegister(void)
Definition: main.c:186
bbextentt
fixed16_t bbextentt
Definition: main.c:120
WARP_WIDTH
#define WARP_WIDTH
Definition: sw.h:64
sw_maxedges
cvar_t * sw_maxedges
Definition: main.c:80
R_Init
qboolean R_Init(qboolean total)
Definition: main.c:234
screenedge
cplane_t screenedge[4]
Definition: main.c:59
viddef_t::rowbytes
int rowbytes
Definition: sw.h:125
r_numallocatededges
int r_numallocatededges
Definition: main.c:36
sw_drawflat
cvar_t * sw_drawflat
Definition: main.c:78
Com_Error
void Com_Error(error_type_t type, const char *fmt,...)
Definition: g_main.c:258
BSP_Free
void BSP_Free(bsp_t *bsp)
Definition: bsp.c:932
Cmd_RemoveCommand
void Cmd_RemoveCommand(const char *name)
Definition: cmd.c:1593
clipplane_s::leftedge
byte leftedge
Definition: sw.h:197
clipplane_s::rightedge
byte rightedge
Definition: sw.h:198
forward
static vec3_t forward
Definition: p_view.c:27
d_tdivzorigin
float d_tdivzorigin
Definition: main.c:118
pixel_t
unsigned char pixel_t
Definition: sw.h:121
intsintable
int intsintable[CYCLE *2]
Definition: main.c:134
NUMSTACKEDGES
#define NUMSTACKEDGES
Definition: sw.h:78
vpn
vec3_t vpn
Definition: main.c:50
R_DrawSubmodelPolygons
void R_DrawSubmodelPolygons(mmodel_t *pmodel, int clipflags, mnode_t *topnode)
Definition: bsp.c:313
sw.h
Z_Free
void Z_Free(void *ptr)
Definition: zone.c:147
R_DrawAlphaSurfaces
void R_DrawAlphaSurfaces(void)
Definition: poly.c:764
R_ApplySIRDAlgorithum
void R_ApplySIRDAlgorithum(void)
Definition: sird.c:155
R_InitCaches
void R_InitCaches(void)
Definition: surf.c:172
d_spantable
byte * d_spantable[MAXHEIGHT]
Definition: main.c:130
IMG_Shutdown
void IMG_Shutdown(void)
Definition: images.c:1448
R_RenderFrame
void R_RenderFrame(refdef_t *fd)
Definition: main.c:803
CACHE_SIZE
#define CACHE_SIZE
Definition: sw.h:47
r_time1
float r_time1
Definition: main.c:35
VID_Shutdown
void VID_Shutdown(void)
Definition: glimp.c:54
origin
static vec3_t origin
Definition: mesh.c:27
AngleVectors
void AngleVectors(vec3_t angles, vec3_t forward, vec3_t right, vec3_t up)
Definition: shared.c:23
d_zwidth
int d_zwidth
Definition: main.c:129
d_zspantable
short * d_zspantable[MAXHEIGHT]
Definition: main.c:131
d_tdivzstepv
float d_tdivzstepv
Definition: main.c:117
R_TransformFrustum
void R_TransformFrustum(void)
Definition: misc.c:70
R_MarkLeaves
static void R_MarkLeaves(void)
Definition: main.c:375
sw_aliasstats
cvar_t * sw_aliasstats
Definition: main.c:76
sintable
int sintable[CYCLE *2]
Definition: main.c:133
R_AddDecal
void R_AddDecal(decal_t *d)
Definition: main.c:923
sw_clearcolor
cvar_t * sw_clearcolor
Definition: main.c:77
r_entorigin
vec3_t r_entorigin
Definition: bsp.c:29
r_outofsurfaces
int r_outofsurfaces
Definition: main.c:37
NUM_BEAM_SEGS
#define NUM_BEAM_SEGS
modelorg
vec3_t modelorg
Definition: bsp.c:27
VID_Init
qboolean VID_Init(void)
Definition: glimp.c:430
sw_dynamic
cvar_t * sw_dynamic
Definition: main.c:86
MOD_Shutdown
void MOD_Shutdown(void)
Definition: models.c:459
r_lerpmodels
cvar_t * r_lerpmodels
Definition: main.c:99
r_drawnpolycount
int r_drawnpolycount
Definition: main.c:67
r_worldentity
entity_t r_worldentity
Definition: main.c:26
RotatePointAroundVector
void RotatePointAroundVector(vec3_t dst, const vec3_t dir, const vec3_t point, float degrees)
Definition: math.c:348
VID_BYTES
#define VID_BYTES
Definition: sw.h:49
r_novis
cvar_t * r_novis
Definition: main.c:100
r_visframecount
int r_visframecount
Definition: main.c:65
R_BmodelCheckBBox
static int R_BmodelCheckBBox(float *minmaxs)
Definition: main.c:506
r_wholepolycount
int r_wholepolycount
Definition: main.c:68
r_warpbuffer
byte r_warpbuffer[WARP_WIDTH *WARP_HEIGHT *VID_BYTES]
Definition: main.c:33
d_tdivzstepu
float d_tdivzstepu
Definition: main.c:116
surfaces
surf_t * surfaces
Definition: edge.c:35
R_ModeChanged
void R_ModeChanged(int width, int height, int flags, int rowbytes, void *pixels)
Definition: main.c:191
d_zistepv
float d_zistepv
Definition: main.c:117
d_pzbuffer
short * d_pzbuffer
Definition: main.c:127
oldrefdef_t
Definition: sw.h:131
auxedges
edge_t * auxedges
Definition: edge.c:31
sw_modulate
cvar_t * sw_modulate
Definition: main.c:87
sadjust
fixed16_t sadjust
Definition: main.c:120
d_sdivzstepu
float d_sdivzstepu
Definition: main.c:116
d_sdivzorigin
float d_sdivzorigin
Definition: main.c:118
R_RotateBmodel
void R_RotateBmodel(void)
Definition: bsp.c:71
WARP_HEIGHT
#define WARP_HEIGHT
Definition: sw.h:65
up
static vec3_t up
Definition: p_view.c:27
D_FlushCaches
void D_FlushCaches(void)
Definition: surf.c:222
Cvar_ClampInteger
int Cvar_ClampInteger(cvar_t *var, int min, int max)
Definition: cvar.c:549
R_InitSkyBox
void R_InitSkyBox(void)
Definition: sky.c:77
sw_waterwarp
cvar_t * sw_waterwarp
Definition: main.c:85
right
static vec3_t right
Definition: p_view.c:27
vid_gamma
cvar_t * vid_gamma
Definition: main.c:104
R_SetClipRect
void(* R_SetClipRect)(const clipRect_t *clip)
Definition: refresh.c:414
R_EdgeDrawing
static void R_EdgeDrawing(void)
Definition: main.c:731
r_maxsurfsseen
int r_maxsurfsseen
Definition: main.c:43
surf_max
surf_t * surf_max
Definition: edge.c:35
R_InitTurb
void R_InitTurb(void)
Definition: main.c:142
surface_p
surf_t * surface_p
Definition: edge.c:35
r_clipflags
int r_clipflags
Definition: main.c:44
R_InitDraw
void R_InitDraw(void)
Definition: draw.c:109
R_FreeCaches
void R_FreeCaches(void)
Definition: surf.c:206
color
static vec4_t color
Definition: mesh.c:33
tadjust
fixed16_t tadjust
Definition: main.c:120
clipplane_s::dist
float dist
Definition: sw.h:195
insubmodel
qboolean insubmodel
Definition: bsp.c:25
sw_reportsurfout
cvar_t * sw_reportsurfout
Definition: main.c:83
r_oldviewcluster
int r_oldviewcluster
Definition: main.c:74
VID_BeginFrame
void VID_BeginFrame(void)
Definition: glimp.c:505
R_IMFlatShadedQuad
void R_IMFlatShadedQuad(vec3_t a, vec3_t b, vec3_t c, vec3_t d, color_t color, float alpha)
Definition: poly.c:791
sw_drawsird
cvar_t * sw_drawsird
Definition: main.c:93
sw_mipscale
cvar_t * sw_mipscale
Definition: misc.c:25
R_BeginFrame
void R_BeginFrame(void)
Definition: main.c:858
vid
viddef_t vid
Definition: main.c:22
R_RenderWorld
void R_RenderWorld(void)
Definition: bsp.c:474
r_worldmodel
bsp_t * r_worldmodel
Definition: main.c:31
MAXHEIGHT
#define MAXHEIGHT
Definition: sw.h:57
R_SetupFrame
void R_SetupFrame(void)
Definition: misc.c:243
pfrustum_indexes
int * pfrustum_indexes[4]
Definition: main.c:70
R_DrawSolidClippedSubmodelPolygons
void R_DrawSolidClippedSubmodelPolygons(mmodel_t *pmodel, mnode_t *topnode)
Definition: bsp.c:245
R_MarkLights
void R_MarkLights(mnode_t *headnode)
Definition: light.c:76
view_clipplanes
clipplane_t view_clipplanes[4]
Definition: raster.c:37
sw_lockpvs
cvar_t * sw_lockpvs
Definition: main.c:88
IMG_Init
void IMG_Init(void)
Definition: images.c:1419
bbextents
fixed16_t bbextents
Definition: main.c:120
currentmodel
model_t * currentmodel
Definition: main.c:29
base_vpn
vec3_t base_vpn
Definition: main.c:50
d_ziorigin
float d_ziorigin
Definition: main.c:118
VectorNormalize
vec_t VectorNormalize(vec3_t v)
Definition: shared.c:55
R_DrawEntitiesOnList
static void R_DrawEntitiesOnList(void)
Definition: main.c:487
surf_s
Definition: sw.h:243
auxsurfaces
surf_t * auxsurfaces
Definition: edge.c:34
MAXEDGES
#define MAXEDGES
Definition: sw.h:80
edge_s
Definition: sw.h:260
r_speeds
cvar_t * r_speeds
Definition: main.c:102
vright
vec3_t vright
Definition: main.c:51
R_PrintTimes
void R_PrintTimes(void)
Definition: misc.c:38