r_edge.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771
  1. /*
  2. Copyright (C) 1996-1997 Id Software, Inc.
  3. This program is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU General Public License
  5. as published by the Free Software Foundation; either version 2
  6. of the License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. See the GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  14. */
  15. // r_edge.c
  16. #include "quakedef.h"
  17. #include "r_local.h"
  18. #if 0
  19. // FIXME
  20. the complex cases add new polys on most lines, so dont optimize for keeping them the same
  21. have multiple free span lists to try to get better coherence?
  22. low depth complexity -- 1 to 3 or so
  23. this breaks spans at every edge, even hidden ones (bad)
  24. have a sentinal at both ends?
  25. #endif
  26. edge_t *auxedges;
  27. edge_t *r_edges, *edge_p, *edge_max;
  28. surf_t *surfaces, *surface_p, *surf_max;
  29. // surfaces are generated in back to front order by the bsp, so if a surf
  30. // pointer is greater than another one, it should be drawn in front
  31. // surfaces[1] is the background, and is used as the active surface stack
  32. edge_t *newedges[MAXHEIGHT];
  33. edge_t *removeedges[MAXHEIGHT];
  34. espan_t *span_p, *max_span_p;
  35. int r_currentkey;
  36. extern int screenwidth;
  37. int current_iv;
  38. int edge_head_u_shift20, edge_tail_u_shift20;
  39. static void (*pdrawfunc)(void);
  40. edge_t edge_head;
  41. edge_t edge_tail;
  42. edge_t edge_aftertail;
  43. edge_t edge_sentinel;
  44. float fv;
  45. void R_GenerateSpans (void);
  46. void R_GenerateSpansBackward (void);
  47. void R_LeadingEdge (edge_t *edge);
  48. void R_LeadingEdgeBackwards (edge_t *edge);
  49. void R_TrailingEdge (surf_t *surf, edge_t *edge);
  50. //=============================================================================
  51. /*
  52. ==============
  53. R_DrawCulledPolys
  54. ==============
  55. */
  56. void R_DrawCulledPolys (void)
  57. {
  58. surf_t *s;
  59. msurface_t *pface;
  60. currententity = &r_worldentity;
  61. if (r_worldpolysbacktofront)
  62. {
  63. for (s=surface_p-1 ; s>&surfaces[1] ; s--)
  64. {
  65. if (!s->spans)
  66. continue;
  67. if (!(s->flags & SURF_DRAWBACKGROUND))
  68. {
  69. pface = (msurface_t *)s->data;
  70. R_RenderPoly (pface, 15);
  71. }
  72. }
  73. }
  74. else
  75. {
  76. for (s = &surfaces[1] ; s<surface_p ; s++)
  77. {
  78. if (!s->spans)
  79. continue;
  80. if (!(s->flags & SURF_DRAWBACKGROUND))
  81. {
  82. pface = (msurface_t *)s->data;
  83. R_RenderPoly (pface, 15);
  84. }
  85. }
  86. }
  87. }
  88. /*
  89. ==============
  90. R_BeginEdgeFrame
  91. ==============
  92. */
  93. void R_BeginEdgeFrame (void)
  94. {
  95. int v;
  96. edge_p = r_edges;
  97. edge_max = &r_edges[r_numallocatededges];
  98. surface_p = &surfaces[2]; // background is surface 1,
  99. // surface 0 is a dummy
  100. surfaces[1].spans = NULL; // no background spans yet
  101. surfaces[1].flags = SURF_DRAWBACKGROUND;
  102. // put the background behind everything in the world
  103. if (r_draworder.value)
  104. {
  105. pdrawfunc = R_GenerateSpansBackward;
  106. surfaces[1].key = 0;
  107. r_currentkey = 1;
  108. }
  109. else
  110. {
  111. pdrawfunc = R_GenerateSpans;
  112. surfaces[1].key = 0x7FFFFFFF;
  113. r_currentkey = 0;
  114. }
  115. // FIXME: set with memset
  116. for (v=r_refdef.vrect.y ; v<r_refdef.vrectbottom ; v++)
  117. {
  118. newedges[v] = removeedges[v] = NULL;
  119. }
  120. }
  121. #if !id386
  122. /*
  123. ==============
  124. R_InsertNewEdges
  125. Adds the edges in the linked list edgestoadd, adding them to the edges in the
  126. linked list edgelist. edgestoadd is assumed to be sorted on u, and non-empty (this is actually newedges[v]). edgelist is assumed to be sorted on u, with a
  127. sentinel at the end (actually, this is the active edge table starting at
  128. edge_head.next).
  129. ==============
  130. */
  131. void R_InsertNewEdges (edge_t *edgestoadd, edge_t *edgelist)
  132. {
  133. edge_t *next_edge;
  134. do
  135. {
  136. next_edge = edgestoadd->next;
  137. edgesearch:
  138. if (edgelist->u >= edgestoadd->u)
  139. goto addedge;
  140. edgelist=edgelist->next;
  141. if (edgelist->u >= edgestoadd->u)
  142. goto addedge;
  143. edgelist=edgelist->next;
  144. if (edgelist->u >= edgestoadd->u)
  145. goto addedge;
  146. edgelist=edgelist->next;
  147. if (edgelist->u >= edgestoadd->u)
  148. goto addedge;
  149. edgelist=edgelist->next;
  150. goto edgesearch;
  151. // insert edgestoadd before edgelist
  152. addedge:
  153. edgestoadd->next = edgelist;
  154. edgestoadd->prev = edgelist->prev;
  155. edgelist->prev->next = edgestoadd;
  156. edgelist->prev = edgestoadd;
  157. } while ((edgestoadd = next_edge) != NULL);
  158. }
  159. #endif // !id386
  160. #if !id386
  161. /*
  162. ==============
  163. R_RemoveEdges
  164. ==============
  165. */
  166. void R_RemoveEdges (edge_t *pedge)
  167. {
  168. do
  169. {
  170. pedge->next->prev = pedge->prev;
  171. pedge->prev->next = pedge->next;
  172. } while ((pedge = pedge->nextremove) != NULL);
  173. }
  174. #endif // !id386
  175. #if !id386
  176. /*
  177. ==============
  178. R_StepActiveU
  179. ==============
  180. */
  181. void R_StepActiveU (edge_t *pedge)
  182. {
  183. edge_t *pnext_edge, *pwedge;
  184. while (1)
  185. {
  186. nextedge:
  187. pedge->u += pedge->u_step;
  188. if (pedge->u < pedge->prev->u)
  189. goto pushback;
  190. pedge = pedge->next;
  191. pedge->u += pedge->u_step;
  192. if (pedge->u < pedge->prev->u)
  193. goto pushback;
  194. pedge = pedge->next;
  195. pedge->u += pedge->u_step;
  196. if (pedge->u < pedge->prev->u)
  197. goto pushback;
  198. pedge = pedge->next;
  199. pedge->u += pedge->u_step;
  200. if (pedge->u < pedge->prev->u)
  201. goto pushback;
  202. pedge = pedge->next;
  203. goto nextedge;
  204. pushback:
  205. if (pedge == &edge_aftertail)
  206. return;
  207. // push it back to keep it sorted
  208. pnext_edge = pedge->next;
  209. // pull the edge out of the edge list
  210. pedge->next->prev = pedge->prev;
  211. pedge->prev->next = pedge->next;
  212. // find out where the edge goes in the edge list
  213. pwedge = pedge->prev->prev;
  214. while (pwedge->u > pedge->u)
  215. {
  216. pwedge = pwedge->prev;
  217. }
  218. // put the edge back into the edge list
  219. pedge->next = pwedge->next;
  220. pedge->prev = pwedge;
  221. pedge->next->prev = pedge;
  222. pwedge->next = pedge;
  223. pedge = pnext_edge;
  224. if (pedge == &edge_tail)
  225. return;
  226. }
  227. }
  228. #endif // !id386
  229. /*
  230. ==============
  231. R_CleanupSpan
  232. ==============
  233. */
  234. void R_CleanupSpan ()
  235. {
  236. surf_t *surf;
  237. int iu;
  238. espan_t *span;
  239. // now that we've reached the right edge of the screen, we're done with any
  240. // unfinished surfaces, so emit a span for whatever's on top
  241. surf = surfaces[1].next;
  242. iu = edge_tail_u_shift20;
  243. if (iu > surf->last_u)
  244. {
  245. span = span_p++;
  246. span->u = surf->last_u;
  247. span->count = iu - span->u;
  248. span->v = current_iv;
  249. span->pnext = surf->spans;
  250. surf->spans = span;
  251. }
  252. // reset spanstate for all surfaces in the surface stack
  253. do
  254. {
  255. surf->spanstate = 0;
  256. surf = surf->next;
  257. } while (surf != &surfaces[1]);
  258. }
  259. /*
  260. ==============
  261. R_LeadingEdgeBackwards
  262. ==============
  263. */
  264. void R_LeadingEdgeBackwards (edge_t *edge)
  265. {
  266. espan_t *span;
  267. surf_t *surf, *surf2;
  268. int iu;
  269. // it's adding a new surface in, so find the correct place
  270. surf = &surfaces[edge->surfs[1]];
  271. // don't start a span if this is an inverted span, with the end
  272. // edge preceding the start edge (that is, we've already seen the
  273. // end edge)
  274. if (++surf->spanstate == 1)
  275. {
  276. surf2 = surfaces[1].next;
  277. if (surf->key > surf2->key)
  278. goto newtop;
  279. // if it's two surfaces on the same plane, the one that's already
  280. // active is in front, so keep going unless it's a bmodel
  281. if (surf->insubmodel && (surf->key == surf2->key))
  282. {
  283. // must be two bmodels in the same leaf; don't care, because they'll
  284. // never be farthest anyway
  285. goto newtop;
  286. }
  287. continue_search:
  288. do
  289. {
  290. surf2 = surf2->next;
  291. } while (surf->key < surf2->key);
  292. if (surf->key == surf2->key)
  293. {
  294. // if it's two surfaces on the same plane, the one that's already
  295. // active is in front, so keep going unless it's a bmodel
  296. if (!surf->insubmodel)
  297. goto continue_search;
  298. // must be two bmodels in the same leaf; don't care which is really
  299. // in front, because they'll never be farthest anyway
  300. }
  301. goto gotposition;
  302. newtop:
  303. // emit a span (obscures current top)
  304. iu = edge->u >> 20;
  305. if (iu > surf2->last_u)
  306. {
  307. span = span_p++;
  308. span->u = surf2->last_u;
  309. span->count = iu - span->u;
  310. span->v = current_iv;
  311. span->pnext = surf2->spans;
  312. surf2->spans = span;
  313. }
  314. // set last_u on the new span
  315. surf->last_u = iu;
  316. gotposition:
  317. // insert before surf2
  318. surf->next = surf2;
  319. surf->prev = surf2->prev;
  320. surf2->prev->next = surf;
  321. surf2->prev = surf;
  322. }
  323. }
  324. /*
  325. ==============
  326. R_TrailingEdge
  327. ==============
  328. */
  329. void R_TrailingEdge (surf_t *surf, edge_t *edge)
  330. {
  331. espan_t *span;
  332. int iu;
  333. // don't generate a span if this is an inverted span, with the end
  334. // edge preceding the start edge (that is, we haven't seen the
  335. // start edge yet)
  336. if (--surf->spanstate == 0)
  337. {
  338. if (surf->insubmodel)
  339. r_bmodelactive--;
  340. if (surf == surfaces[1].next)
  341. {
  342. // emit a span (current top going away)
  343. iu = edge->u >> 20;
  344. if (iu > surf->last_u)
  345. {
  346. span = span_p++;
  347. span->u = surf->last_u;
  348. span->count = iu - span->u;
  349. span->v = current_iv;
  350. span->pnext = surf->spans;
  351. surf->spans = span;
  352. }
  353. // set last_u on the surface below
  354. surf->next->last_u = iu;
  355. }
  356. surf->prev->next = surf->next;
  357. surf->next->prev = surf->prev;
  358. }
  359. }
  360. #if !id386
  361. /*
  362. ==============
  363. R_LeadingEdge
  364. ==============
  365. */
  366. void R_LeadingEdge (edge_t *edge)
  367. {
  368. espan_t *span;
  369. surf_t *surf, *surf2;
  370. int iu;
  371. double fu, newzi, testzi, newzitop, newzibottom;
  372. if (edge->surfs[1])
  373. {
  374. // it's adding a new surface in, so find the correct place
  375. surf = &surfaces[edge->surfs[1]];
  376. // don't start a span if this is an inverted span, with the end
  377. // edge preceding the start edge (that is, we've already seen the
  378. // end edge)
  379. if (++surf->spanstate == 1)
  380. {
  381. if (surf->insubmodel)
  382. r_bmodelactive++;
  383. surf2 = surfaces[1].next;
  384. if (surf->key < surf2->key)
  385. goto newtop;
  386. // if it's two surfaces on the same plane, the one that's already
  387. // active is in front, so keep going unless it's a bmodel
  388. if (surf->insubmodel && (surf->key == surf2->key))
  389. {
  390. // must be two bmodels in the same leaf; sort on 1/z
  391. fu = (float)(edge->u - 0xFFFFF) * (1.0 / 0x100000);
  392. newzi = surf->d_ziorigin + fv*surf->d_zistepv +
  393. fu*surf->d_zistepu;
  394. newzibottom = newzi * 0.99;
  395. testzi = surf2->d_ziorigin + fv*surf2->d_zistepv +
  396. fu*surf2->d_zistepu;
  397. if (newzibottom >= testzi)
  398. {
  399. goto newtop;
  400. }
  401. newzitop = newzi * 1.01;
  402. if (newzitop >= testzi)
  403. {
  404. if (surf->d_zistepu >= surf2->d_zistepu)
  405. {
  406. goto newtop;
  407. }
  408. }
  409. }
  410. continue_search:
  411. do
  412. {
  413. surf2 = surf2->next;
  414. } while (surf->key > surf2->key);
  415. if (surf->key == surf2->key)
  416. {
  417. // if it's two surfaces on the same plane, the one that's already
  418. // active is in front, so keep going unless it's a bmodel
  419. if (!surf->insubmodel)
  420. goto continue_search;
  421. // must be two bmodels in the same leaf; sort on 1/z
  422. fu = (float)(edge->u - 0xFFFFF) * (1.0 / 0x100000);
  423. newzi = surf->d_ziorigin + fv*surf->d_zistepv +
  424. fu*surf->d_zistepu;
  425. newzibottom = newzi * 0.99;
  426. testzi = surf2->d_ziorigin + fv*surf2->d_zistepv +
  427. fu*surf2->d_zistepu;
  428. if (newzibottom >= testzi)
  429. {
  430. goto gotposition;
  431. }
  432. newzitop = newzi * 1.01;
  433. if (newzitop >= testzi)
  434. {
  435. if (surf->d_zistepu >= surf2->d_zistepu)
  436. {
  437. goto gotposition;
  438. }
  439. }
  440. goto continue_search;
  441. }
  442. goto gotposition;
  443. newtop:
  444. // emit a span (obscures current top)
  445. iu = edge->u >> 20;
  446. if (iu > surf2->last_u)
  447. {
  448. span = span_p++;
  449. span->u = surf2->last_u;
  450. span->count = iu - span->u;
  451. span->v = current_iv;
  452. span->pnext = surf2->spans;
  453. surf2->spans = span;
  454. }
  455. // set last_u on the new span
  456. surf->last_u = iu;
  457. gotposition:
  458. // insert before surf2
  459. surf->next = surf2;
  460. surf->prev = surf2->prev;
  461. surf2->prev->next = surf;
  462. surf2->prev = surf;
  463. }
  464. }
  465. }
  466. /*
  467. ==============
  468. R_GenerateSpans
  469. ==============
  470. */
  471. void R_GenerateSpans (void)
  472. {
  473. edge_t *edge;
  474. surf_t *surf;
  475. r_bmodelactive = 0;
  476. // clear active surfaces to just the background surface
  477. surfaces[1].next = surfaces[1].prev = &surfaces[1];
  478. surfaces[1].last_u = edge_head_u_shift20;
  479. // generate spans
  480. for (edge=edge_head.next ; edge != &edge_tail; edge=edge->next)
  481. {
  482. if (edge->surfs[0])
  483. {
  484. // it has a left surface, so a surface is going away for this span
  485. surf = &surfaces[edge->surfs[0]];
  486. R_TrailingEdge (surf, edge);
  487. if (!edge->surfs[1])
  488. continue;
  489. }
  490. R_LeadingEdge (edge);
  491. }
  492. R_CleanupSpan ();
  493. }
  494. #endif // !id386
  495. /*
  496. ==============
  497. R_GenerateSpansBackward
  498. ==============
  499. */
  500. void R_GenerateSpansBackward (void)
  501. {
  502. edge_t *edge;
  503. r_bmodelactive = 0;
  504. // clear active surfaces to just the background surface
  505. surfaces[1].next = surfaces[1].prev = &surfaces[1];
  506. surfaces[1].last_u = edge_head_u_shift20;
  507. // generate spans
  508. for (edge=edge_head.next ; edge != &edge_tail; edge=edge->next)
  509. {
  510. if (edge->surfs[0])
  511. R_TrailingEdge (&surfaces[edge->surfs[0]], edge);
  512. if (edge->surfs[1])
  513. R_LeadingEdgeBackwards (edge);
  514. }
  515. R_CleanupSpan ();
  516. }
  517. /*
  518. ==============
  519. R_ScanEdges
  520. Input:
  521. newedges[] array
  522. this has links to edges, which have links to surfaces
  523. Output:
  524. Each surface has a linked list of its visible spans
  525. ==============
  526. */
  527. void R_ScanEdges (void)
  528. {
  529. int iv, bottom;
  530. byte basespans[MAXSPANS*sizeof(espan_t)+CACHE_SIZE];
  531. espan_t *basespan_p;
  532. surf_t *s;
  533. basespan_p = (espan_t *)
  534. ((long)(basespans + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1));
  535. max_span_p = &basespan_p[MAXSPANS - r_refdef.vrect.width];
  536. span_p = basespan_p;
  537. // clear active edges to just the background edges around the whole screen
  538. // FIXME: most of this only needs to be set up once
  539. edge_head.u = r_refdef.vrect.x << 20;
  540. edge_head_u_shift20 = edge_head.u >> 20;
  541. edge_head.u_step = 0;
  542. edge_head.prev = NULL;
  543. edge_head.next = &edge_tail;
  544. edge_head.surfs[0] = 0;
  545. edge_head.surfs[1] = 1;
  546. edge_tail.u = (r_refdef.vrectright << 20) + 0xFFFFF;
  547. edge_tail_u_shift20 = edge_tail.u >> 20;
  548. edge_tail.u_step = 0;
  549. edge_tail.prev = &edge_head;
  550. edge_tail.next = &edge_aftertail;
  551. edge_tail.surfs[0] = 1;
  552. edge_tail.surfs[1] = 0;
  553. edge_aftertail.u = -1; // force a move
  554. edge_aftertail.u_step = 0;
  555. edge_aftertail.next = &edge_sentinel;
  556. edge_aftertail.prev = &edge_tail;
  557. // FIXME: do we need this now that we clamp x in r_draw.c?
  558. edge_sentinel.u = 2000 << 24; // make sure nothing sorts past this
  559. edge_sentinel.prev = &edge_aftertail;
  560. //
  561. // process all scan lines
  562. //
  563. bottom = r_refdef.vrectbottom - 1;
  564. for (iv=r_refdef.vrect.y ; iv<bottom ; iv++)
  565. {
  566. current_iv = iv;
  567. fv = (float)iv;
  568. // mark that the head (background start) span is pre-included
  569. surfaces[1].spanstate = 1;
  570. if (newedges[iv])
  571. {
  572. R_InsertNewEdges (newedges[iv], edge_head.next);
  573. }
  574. (*pdrawfunc) ();
  575. // flush the span list if we can't be sure we have enough spans left for
  576. // the next scan
  577. if (span_p > max_span_p)
  578. {
  579. VID_UnlockBuffer ();
  580. S_ExtraUpdate (); // don't let sound get messed up if going slow
  581. VID_LockBuffer ();
  582. if (r_drawculledpolys)
  583. R_DrawCulledPolys ();
  584. else
  585. D_DrawSurfaces ();
  586. // clear the surface span pointers
  587. for (s = &surfaces[1] ; s<surface_p ; s++)
  588. s->spans = NULL;
  589. span_p = basespan_p;
  590. }
  591. if (removeedges[iv])
  592. R_RemoveEdges (removeedges[iv]);
  593. if (edge_head.next != &edge_tail)
  594. R_StepActiveU (edge_head.next);
  595. }
  596. // do the last scan (no need to step or sort or remove on the last scan)
  597. current_iv = iv;
  598. fv = (float)iv;
  599. // mark that the head (background start) span is pre-included
  600. surfaces[1].spanstate = 1;
  601. if (newedges[iv])
  602. R_InsertNewEdges (newedges[iv], edge_head.next);
  603. (*pdrawfunc) ();
  604. // draw whatever's left in the span list
  605. if (r_drawculledpolys)
  606. R_DrawCulledPolys ();
  607. else
  608. D_DrawSurfaces ();
  609. }