diff options
-rw-r--r-- | apps/plugins/sdl/progs/quake/d_scan.c | 190 | ||||
-rw-r--r-- | apps/plugins/sdl/progs/quake/model.c | 16 | ||||
-rw-r--r-- | apps/plugins/sdl/progs/quake/quakedef.h | 2 | ||||
-rw-r--r-- | apps/plugins/sdl/progs/quake/r_draw.c | 491 | ||||
-rw-r--r-- | apps/plugins/sdl/progs/quake/r_local.h | 21 | ||||
-rw-r--r-- | apps/plugins/sdl/progs/quake/r_main.c | 7 | ||||
-rw-r--r-- | apps/plugins/sdl/progs/quake/r_misc.c | 44 |
7 files changed, 767 insertions, 4 deletions
diff --git a/apps/plugins/sdl/progs/quake/d_scan.c b/apps/plugins/sdl/progs/quake/d_scan.c index 008c783be6..a2e58649e3 100644 --- a/apps/plugins/sdl/progs/quake/d_scan.c +++ b/apps/plugins/sdl/progs/quake/d_scan.c | |||
@@ -254,6 +254,7 @@ void Turbulent8 (espan_t *pspan) | |||
254 | D_DrawSpans8 | 254 | D_DrawSpans8 |
255 | ============= | 255 | ============= |
256 | */ | 256 | */ |
257 | #ifndef USE_PQ_OPT5 | ||
257 | void D_DrawSpans8 (espan_t *pspan) | 258 | void D_DrawSpans8 (espan_t *pspan) |
258 | { | 259 | { |
259 | int count, spancount; | 260 | int count, spancount; |
@@ -381,8 +382,197 @@ void D_DrawSpans8 (espan_t *pspan) | |||
381 | 382 | ||
382 | } while ((pspan = pspan->pnext) != NULL); | 383 | } while ((pspan = pspan->pnext) != NULL); |
383 | } | 384 | } |
385 | #else | ||
384 | 386 | ||
387 | static int sdivzorig, sdivzstepv, sdivzstepu, sdivz8stepu; | ||
388 | static int tdivzorig, tdivzstepv, tdivzstepu, tdivz8stepu; | ||
389 | static int zi8stepu; | ||
390 | static float last = 0; | ||
391 | |||
392 | /*============================================== | ||
393 | // UpdateFixedPointVars | ||
394 | //============================================*/ | ||
395 | void UpdateFixedPointVars( int all ) | ||
396 | { | ||
397 | // JB: Store texture transformation matrix in fixed point vars | ||
398 | if (all) | ||
399 | { | ||
400 | /* | ||
401 | sdivzorig = (int)(524288.0f * d_sdivzorigin); // 13.19 fixed point | ||
402 | tdivzorig = (int)(524288.0f * d_tdivzorigin); | ||
403 | sdivzstepv = (int)(524288.0f * d_sdivzstepv); | ||
404 | tdivzstepv = (int)(524288.0f * d_tdivzstepv); | ||
405 | sdivzstepu = (int)(524288.0f * d_sdivzstepu); | ||
406 | sdivz8stepu = sdivzstepu*8; | ||
407 | tdivzstepu = (int)(524288.0f * d_tdivzstepu); | ||
408 | tdivz8stepu = tdivzstepu*8; | ||
409 | */ | ||
410 | |||
411 | sdivzorig = (int)(4194304.0f * d_sdivzorigin); // 10.22 fixed point | ||
412 | tdivzorig = (int)(4194304.0f * d_tdivzorigin); | ||
413 | sdivzstepv = (int)(4194304.0f * d_sdivzstepv); | ||
414 | tdivzstepv = (int)(4194304.0f * d_tdivzstepv); | ||
415 | sdivzstepu = (int)(4194304.0f * d_sdivzstepu); | ||
416 | sdivz8stepu = sdivzstepu*8; | ||
417 | tdivzstepu = (int)(4194304.0f * d_tdivzstepu); | ||
418 | tdivz8stepu = tdivzstepu*8; | ||
419 | |||
420 | } | ||
421 | /* | ||
422 | ziorig = (int)(524288.0f * d_ziorigin); // 13.19 fixed point | ||
423 | zistepv = (int)(524288.0f * d_zistepv ); | ||
424 | zistepu = (int)(524288.0f * d_zistepu ); | ||
425 | */ | ||
426 | #ifndef USE_PQ_OPT3 | ||
427 | d_ziorigin_fxp = (int)(4194304.0f * d_ziorigin); // 10.22 fixed point | ||
428 | d_zistepv_fxp = (int)(4194304.0f * d_zistepv ); | ||
429 | d_zistepu_fxp = (int)(4194304.0f * d_zistepu ); | ||
430 | #endif | ||
431 | |||
432 | zi8stepu = d_zistepu_fxp * 8; | ||
433 | last = d_zistepv; | ||
434 | } | ||
435 | |||
436 | void D_DrawSpans8 (espan_t *pspan) | ||
437 | { | ||
438 | int count, spancount, spancountminus1; | ||
439 | unsigned char *pbase, *pdest; | ||
440 | fixed16_t s1, t1; | ||
441 | int zi, sdivz, tdivz, sstep, tstep; | ||
442 | int snext, tnext; | ||
443 | pbase = (unsigned char *)cacheblock; | ||
444 | //Jacco Biker's fixed point conversion | ||
445 | |||
446 | // Recalc fixed point values | ||
447 | UpdateFixedPointVars( 1 ); | ||
448 | do | ||
449 | { | ||
450 | pdest = (unsigned char *)((byte *)d_viewbuffer + (screenwidth * pspan->v) + pspan->u); | ||
451 | count = pspan->count; | ||
452 | // calculate the initial s/z, t/z, 1/z, s, and t and clamp | ||
453 | sdivz = sdivzorig + pspan->v * sdivzstepv + pspan->u * sdivzstepu; | ||
454 | tdivz = tdivzorig + pspan->v * tdivzstepv + pspan->u * tdivzstepu; | ||
455 | zi = d_ziorigin_fxp + pspan->v * d_zistepv_fxp + pspan->u * d_zistepu_fxp; | ||
456 | if (zi == 0) zi = 1; | ||
457 | s1 = (((sdivz << 8) / zi) << 8) + sadjust; // 5.27 / 13.19 = 24.8 >> 8 = 16.16 | ||
458 | if (s1 > bbextents) s1 = bbextents; else if (s1 < 0) s1 = 0; | ||
459 | t1 = (((tdivz << 8) / zi) << 8) + tadjust; | ||
460 | if (t1 > bbextentt) t1 = bbextentt; else if (t1 < 0) t1 = 0; | ||
461 | // calculate final s/z, t/z, 1/z, s, and t and clamp | ||
462 | //sdivz += sdivzstepu * (count - 1); | ||
463 | //tdivz += tdivzstepu * (count - 1); | ||
464 | //zi += d_zistepu_fxp * (count - 1); | ||
465 | //if (zi == 0) zi = 1; | ||
466 | #if 0 | ||
467 | s2 = (((sdivz << 8) / zi) << 8) + sadjust; | ||
468 | if (s2 > bbextents) s2 = bbextents; else if (s2 < 8) s2 = 8; | ||
469 | t2 = (((tdivz << 8) / zi) << 8) + tadjust; | ||
470 | if (t2 > bbextentt) t2 = bbextentt; else if (t2 < 8) t2 = 8; | ||
471 | if (count > 1) | ||
472 | { | ||
473 | sstep = (s2 - s1) / (count - 1); | ||
474 | tstep = (t2 - t1) / (count - 1); | ||
475 | } | ||
476 | #else | ||
477 | //End Jacco Biker mod | ||
478 | //Dan East: Fixed point conversion for perspective correction | ||
479 | do | ||
480 | { | ||
481 | // calculate s and t at the far end of the span | ||
482 | if (count >= 8) | ||
483 | spancount = 8; | ||
484 | else | ||
485 | spancount = count; | ||
486 | |||
487 | count -= spancount; | ||
488 | |||
489 | if (count) | ||
490 | { | ||
491 | // calculate s/z, t/z, zi->fixed s and t at far end of span, | ||
492 | // calculate s and t steps across span by shifting | ||
493 | sdivz += sdivz8stepu; | ||
494 | tdivz += tdivz8stepu; | ||
495 | zi += zi8stepu; | ||
496 | if (!zi) zi = 1; | ||
497 | //z = zi; | ||
498 | //z = (float)0x10000 / zi; // prescale to 16.16 fixed-point | ||
499 | snext = (((sdivz<<8)/zi)<<8)+sadjust; | ||
500 | //snext = (int)(sdivz * z) + sadjust; | ||
501 | if (snext > bbextents) | ||
502 | snext = bbextents; | ||
503 | else if (snext < 8) | ||
504 | snext = 8; // prevent round-off error on <0 steps from | ||
505 | // from causing overstepping & running off the | ||
506 | // edge of the texture | ||
507 | |||
508 | tnext = (((tdivz<<8)/zi)<<8) + tadjust; | ||
509 | if (tnext > bbextentt) | ||
510 | tnext = bbextentt; | ||
511 | else if (tnext < 8) | ||
512 | tnext = 8; // guard against round-off error on <0 steps | ||
513 | |||
514 | sstep = (snext - s1) >> 3; | ||
515 | tstep = (tnext - t1) >> 3; | ||
516 | } | ||
517 | else | ||
518 | { | ||
519 | // calculate s/z, t/z, zi->fixed s and t at last pixel in span (so | ||
520 | // can't step off polygon), clamp, calculate s and t steps across | ||
521 | // span by division, biasing steps low so we don't run off the | ||
522 | // texture | ||
523 | spancountminus1 = spancount - 1; | ||
524 | sdivz += sdivzstepu * spancountminus1; | ||
525 | tdivz += tdivzstepu * spancountminus1; | ||
526 | zi += d_zistepu_fxp * spancountminus1; | ||
527 | if (!zi) zi = 1; | ||
528 | //z = zi;//(float)0x10000 / zi; // prescale to 16.16 fixed-point | ||
529 | snext = (((sdivz<<8) / zi)<<8) + sadjust; | ||
530 | if (snext > bbextents) | ||
531 | snext = bbextents; | ||
532 | else if (snext < 8) | ||
533 | snext = 8; // prevent round-off error on <0 steps from | ||
534 | // from causing overstepping & running off the | ||
535 | // edge of the texture | ||
536 | |||
537 | tnext = (((tdivz<<8) / zi)<<8) + tadjust; | ||
538 | if (tnext > bbextentt) | ||
539 | tnext = bbextentt; | ||
540 | else if (tnext < 8) | ||
541 | tnext = 8; // guard against round-off error on <0 steps | ||
542 | |||
543 | if (spancount > 1) | ||
544 | { | ||
545 | sstep = ((snext - s1)) / ((spancount - 1)); | ||
546 | tstep = ((tnext - t1)) / ((spancount - 1)); | ||
547 | } | ||
548 | } | ||
549 | do | ||
550 | { | ||
551 | *pdest++ = *(pbase + (s1 >> 16) + (t1 >> 16) * cachewidth); | ||
552 | s1 += sstep; | ||
553 | t1 += tstep; | ||
554 | } while (--spancount > 0); | ||
555 | |||
556 | s1 = snext; | ||
557 | t1 = tnext; | ||
558 | |||
559 | } while (count > 0); | ||
385 | #endif | 560 | #endif |
561 | #if 0 | ||
562 | // Draw span | ||
563 | for ( i = 0; i < count; i++ ) | ||
564 | { | ||
565 | *pdest++ = *(pbase + (s1 >> 16) + (t1 >> 16) * cachewidth); | ||
566 | s1 += sstep; | ||
567 | t1 += tstep; | ||
568 | } | ||
569 | #endif | ||
570 | } while ((pspan = pspan->pnext) != NULL); | ||
571 | } | ||
572 | |||
573 | #endif //USE_PQ_OPT5 | ||
574 | |||
575 | #endif // !id386 | ||
386 | 576 | ||
387 | 577 | ||
388 | #if !id386 | 578 | #if !id386 |
diff --git a/apps/plugins/sdl/progs/quake/model.c b/apps/plugins/sdl/progs/quake/model.c index 64c53dfc3e..63a63a4b62 100644 --- a/apps/plugins/sdl/progs/quake/model.c +++ b/apps/plugins/sdl/progs/quake/model.c | |||
@@ -588,6 +588,9 @@ void Mod_LoadVertexes (lump_t *l) | |||
588 | dvertex_t *in; | 588 | dvertex_t *in; |
589 | mvertex_t *out; | 589 | mvertex_t *out; |
590 | int i, count; | 590 | int i, count; |
591 | #ifdef USE_PQ_OPT2 | ||
592 | mvertex_fxp_t *out2; | ||
593 | #endif | ||
591 | 594 | ||
592 | in = (void *)(mod_base + l->fileofs); | 595 | in = (void *)(mod_base + l->fileofs); |
593 | if (l->filelen % sizeof(*in)) | 596 | if (l->filelen % sizeof(*in)) |
@@ -595,6 +598,11 @@ void Mod_LoadVertexes (lump_t *l) | |||
595 | count = l->filelen / sizeof(*in); | 598 | count = l->filelen / sizeof(*in); |
596 | out = Hunk_AllocName ( count*sizeof(*out), loadname); | 599 | out = Hunk_AllocName ( count*sizeof(*out), loadname); |
597 | 600 | ||
601 | #ifdef USE_PQ_OPT2 | ||
602 | out2 = Hunk_AllocName ( count*sizeof(*out2), loadname); | ||
603 | loadmodel->vertexes_fxp = out2; | ||
604 | #endif | ||
605 | |||
598 | loadmodel->vertexes = out; | 606 | loadmodel->vertexes = out; |
599 | loadmodel->numvertexes = count; | 607 | loadmodel->numvertexes = count; |
600 | 608 | ||
@@ -603,6 +611,14 @@ void Mod_LoadVertexes (lump_t *l) | |||
603 | out->position[0] = LittleFloatUnaligned (in->point[0]); | 611 | out->position[0] = LittleFloatUnaligned (in->point[0]); |
604 | out->position[1] = LittleFloatUnaligned (in->point[1]); | 612 | out->position[1] = LittleFloatUnaligned (in->point[1]); |
605 | out->position[2] = LittleFloatUnaligned (in->point[2]); | 613 | out->position[2] = LittleFloatUnaligned (in->point[2]); |
614 | |||
615 | #ifdef USE_PQ_OPT2 | ||
616 | out2->position[0] = (int)(out->position[0]*524288.0f); //13.19 | ||
617 | out2->position[1] = (int)(out->position[1]*524288.0f); //13.19 | ||
618 | out2->position[2] = (int)(out->position[2]*524288.0f); //13.19 | ||
619 | out2++; | ||
620 | #endif | ||
621 | |||
606 | } | 622 | } |
607 | } | 623 | } |
608 | 624 | ||
diff --git a/apps/plugins/sdl/progs/quake/quakedef.h b/apps/plugins/sdl/progs/quake/quakedef.h index 8328154c0b..fe9245e851 100644 --- a/apps/plugins/sdl/progs/quake/quakedef.h +++ b/apps/plugins/sdl/progs/quake/quakedef.h | |||
@@ -31,7 +31,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
31 | #ifdef FIXEDPOINT_OPT | 31 | #ifdef FIXEDPOINT_OPT |
32 | #define USE_PQ_OPT | 32 | #define USE_PQ_OPT |
33 | #define USE_PQ_OPT1 | 33 | #define USE_PQ_OPT1 |
34 | //#define USE_PQ_OPT2 | 34 | #define USE_PQ_OPT2 |
35 | //#define USE_PQ_OPT3 // don't use | 35 | //#define USE_PQ_OPT3 // don't use |
36 | #define USE_PQ_OPT4 | 36 | #define USE_PQ_OPT4 |
37 | //#define USE_PQ_OPT5 | 37 | //#define USE_PQ_OPT5 |
diff --git a/apps/plugins/sdl/progs/quake/r_draw.c b/apps/plugins/sdl/progs/quake/r_draw.c index c4bf95f112..c7da5a8a7e 100644 --- a/apps/plugins/sdl/progs/quake/r_draw.c +++ b/apps/plugins/sdl/progs/quake/r_draw.c | |||
@@ -60,6 +60,11 @@ int intsintable[SIN_BUFFER_SIZE]; | |||
60 | mvertex_t r_leftenter, r_leftexit; | 60 | mvertex_t r_leftenter, r_leftexit; |
61 | mvertex_t r_rightenter, r_rightexit; | 61 | mvertex_t r_rightenter, r_rightexit; |
62 | 62 | ||
63 | #ifdef USE_PQ_OPT2 | ||
64 | mvertex_fxp_t r_leftenter_fxp, r_leftexit_fxp; | ||
65 | mvertex_fxp_t r_rightenter_fxp, r_rightexit_fxp; | ||
66 | #endif | ||
67 | |||
63 | typedef struct | 68 | typedef struct |
64 | { | 69 | { |
65 | float u,v; | 70 | float u,v; |
@@ -259,6 +264,311 @@ void R_EmitEdge (mvertex_t *pv0, mvertex_t *pv1) | |||
259 | removeedges[v2] = edge; | 264 | removeedges[v2] = edge; |
260 | } | 265 | } |
261 | 266 | ||
267 | #ifdef USE_PQ_OPT2 | ||
268 | void R_EmitEdgeFXP_fxp (mvertex_fxp_t *pv0, mvertex_fxp_t *pv1) | ||
269 | { | ||
270 | //This is just like R_EmitEdge_fxp, except that the vertex parameters are | ||
271 | //already fixed point, and don't need to be converted. | ||
272 | |||
273 | edge_t *edge, *pcheck; | ||
274 | int u_check; | ||
275 | //float u, u_step; | ||
276 | int u_fxp, u_step_fxp; | ||
277 | //vec3_t local, transformed; | ||
278 | int local_fxp[3], transformed_fxp[3]; | ||
279 | int *world; | ||
280 | int v, v2, ceilv0; | ||
281 | //float scale, lzi0, u0, v0; | ||
282 | int scale_fxp, scale2_fxp, lzi0_fxp, u0_fxp, v0_fxp; | ||
283 | int side; | ||
284 | |||
285 | if (r_lastvertvalid) | ||
286 | { | ||
287 | u0_fxp = r_u1_fxp; | ||
288 | v0_fxp = r_v1_fxp; | ||
289 | lzi0_fxp = r_lzi1_fxp; | ||
290 | //lzi0 = r_lzi1; | ||
291 | ceilv0 = r_ceilv1; | ||
292 | } | ||
293 | else | ||
294 | { | ||
295 | //world_fxp=(int)(pv0->position[0]*(float)(2^16)); | ||
296 | world = &pv0->position[0]; | ||
297 | |||
298 | // transform and project | ||
299 | //VectorSubtract (world, modelorg, local); | ||
300 | //Vector Subtract (and convert) | ||
301 | local_fxp[0]=world[0]-modelorg_fxp[0]; | ||
302 | local_fxp[1]=world[1]-modelorg_fxp[1]; | ||
303 | local_fxp[2]=world[2]-modelorg_fxp[2]; | ||
304 | |||
305 | //TransformVector (local, transformed); | ||
306 | //transformed_fxp[0] = (int)(local_fxp[0]*vright[0])+(int)(local_fxp[1]*vright[1])+(int)(local_fxp[2]*vright[2]); | ||
307 | //transformed_fxp[1] = (int)(local_fxp[0]*vup[0])+(int)(local_fxp[1]*vup[1])+(int)(local_fxp[2]*vup[2]); | ||
308 | //transformed_fxp[2] = (int)(local_fxp[0]*vpn[0])+(int)(local_fxp[1]*vpn[1])+(int)(local_fxp[2]*vpn[2]); | ||
309 | |||
310 | //13.19 / 24.8 = 21.11 | ||
311 | transformed_fxp[0] = local_fxp[0]/vright_fxp[0]+local_fxp[1]/vright_fxp[1]+local_fxp[2]/vright_fxp[2]; | ||
312 | transformed_fxp[1] = local_fxp[0]/vup_fxp[0]+local_fxp[1]/vup_fxp[1]+local_fxp[2]/vup_fxp[2]; | ||
313 | transformed_fxp[2] = local_fxp[0]/vpn_fxp[0]+local_fxp[1]/vpn_fxp[1]+local_fxp[2]/vpn_fxp[2]; | ||
314 | |||
315 | if (transformed_fxp[2] < (int)(NEAR_CLIP*2048.0)) | ||
316 | transformed_fxp[2] = (int)(NEAR_CLIP*2048.0); | ||
317 | |||
318 | transformed_fxp[0]/=16; //21.11->25.7 | ||
319 | transformed_fxp[1]/=16; //21.11->25.7 | ||
320 | transformed_fxp[2]/=8; //21.11->24.8 | ||
321 | |||
322 | lzi0_fxp=transformed_fxp[2]; | ||
323 | //lzi0 = (float)(1.0 / transformed[2]); | ||
324 | |||
325 | // FIXME: build x/yscale into transform? | ||
326 | //scale = xscale * lzi0; | ||
327 | //u0 = (xcenter + scale*transformed[0]); | ||
328 | |||
329 | //Dan: Is this needed? | ||
330 | if (!transformed_fxp[2]) scale_fxp=0; | ||
331 | else scale_fxp=xscale_fxp/transformed_fxp[2]; //9.23 / 24.8 = 17.15 | ||
332 | scale2_fxp=transformed_fxp[0]*(scale_fxp); // 25.7 * 17.15 = 10.22 | ||
333 | |||
334 | if (transformed_fxp[0]<0) { | ||
335 | if (scale2_fxp>0) scale2_fxp=-511*4194304; | ||
336 | } else { | ||
337 | if (scale2_fxp<0) scale2_fxp=511*4194304; | ||
338 | } | ||
339 | |||
340 | u0_fxp=scale2_fxp+xcenter_fxp; | ||
341 | |||
342 | if (u0_fxp < r_refdef_fvrectx_adj_fxp) | ||
343 | u0_fxp = r_refdef_fvrectx_adj_fxp; | ||
344 | if (u0_fxp > r_refdef_fvrectright_adj_fxp) | ||
345 | u0_fxp = r_refdef_fvrectright_adj_fxp; | ||
346 | |||
347 | //scale = yscale * lzi0; | ||
348 | //v0 = (ycenter - scale*transformed[1]); | ||
349 | |||
350 | //Dan: Is this needed? | ||
351 | if (!transformed_fxp[2]) scale_fxp=0; | ||
352 | else scale_fxp=yscale_fxp/transformed_fxp[2]; //9.23 / 24.8 = 17.15 | ||
353 | scale2_fxp=transformed_fxp[1]*(scale_fxp); // 25.7 * 17.15 = 10.22 | ||
354 | |||
355 | if (transformed_fxp[1]<0) { | ||
356 | if (scale2_fxp>0) scale2_fxp=-511*4194304; | ||
357 | } else { | ||
358 | if (scale2_fxp<0) scale2_fxp=511*4194304; //255*8388608; | ||
359 | } | ||
360 | |||
361 | v0_fxp = ycenter_fxp-scale2_fxp; | ||
362 | |||
363 | if (v0_fxp < r_refdef_fvrecty_adj_fxp) | ||
364 | v0_fxp = r_refdef_fvrecty_adj_fxp; | ||
365 | if (v0_fxp > r_refdef_fvrectbottom_adj_fxp) | ||
366 | v0_fxp = r_refdef_fvrectbottom_adj_fxp; | ||
367 | |||
368 | ceilv0 = v0_fxp/4194304; | ||
369 | if (v0_fxp&0x3FFFFF) ceilv0++; | ||
370 | } | ||
371 | |||
372 | //world(pv1->position[0]*(float)(2^16)); | ||
373 | world = &pv1->position[0]; | ||
374 | |||
375 | // transform and project | ||
376 | //VectorSubtract (world, modelorg, local); | ||
377 | //Vector Subtract (and convert) | ||
378 | local_fxp[0]=world[0]-modelorg_fxp[0]; | ||
379 | local_fxp[1]=world[1]-modelorg_fxp[1]; | ||
380 | local_fxp[2]=world[2]-modelorg_fxp[2]; | ||
381 | |||
382 | //TransformVector (local, transformed); | ||
383 | //transformed_fxp[0] = ((int)(local_fxp[0]*vright[0]))+((int)(local_fxp[1]*vright[1]))+((int)(local_fxp[2]*vright[2])); | ||
384 | //transformed_fxp[1] = ((int)(local_fxp[0]*vup[0]))+((int)(local_fxp[1]*vup[1]))+((int)(local_fxp[2]*vup[2])); | ||
385 | //transformed_fxp[2] = ((int)(local_fxp[0]*vpn[0]))+((int)(local_fxp[1]*vpn[1]))+((int)(local_fxp[2]*vpn[2])); | ||
386 | |||
387 | transformed_fxp[0] = local_fxp[0]/vright_fxp[0]+local_fxp[1]/vright_fxp[1]+local_fxp[2]/vright_fxp[2]; | ||
388 | transformed_fxp[1] = local_fxp[0]/vup_fxp[0]+local_fxp[1]/vup_fxp[1]+local_fxp[2]/vup_fxp[2]; | ||
389 | transformed_fxp[2] = local_fxp[0]/vpn_fxp[0]+local_fxp[1]/vpn_fxp[1]+local_fxp[2]/vpn_fxp[2]; | ||
390 | |||
391 | if (transformed_fxp[2] < (int)(NEAR_CLIP*2048.0)) | ||
392 | transformed_fxp[2] = (int)(NEAR_CLIP*2048.0); | ||
393 | |||
394 | transformed_fxp[0]/=16; | ||
395 | transformed_fxp[1]/=16; | ||
396 | transformed_fxp[2]/=8; | ||
397 | |||
398 | r_lzi1_fxp=transformed_fxp[2]; | ||
399 | //r_lzi1 = (float)(1.0 / transformed[2]); | ||
400 | //scale = xscale * r_lzi1; | ||
401 | |||
402 | //Dan: Is this needed? | ||
403 | if (!transformed_fxp[2]) scale_fxp=0; | ||
404 | else scale_fxp=xscale_fxp/transformed_fxp[2]; //9.23 / 24.8 = 17.15 | ||
405 | scale2_fxp=transformed_fxp[0]*(scale_fxp); // 24.8 * 17.15 = 9.23 //21.11 | ||
406 | |||
407 | if (transformed_fxp[0]<0) { | ||
408 | if (scale2_fxp>0) scale2_fxp=-511*4194304; | ||
409 | } else { | ||
410 | if (scale2_fxp<0) scale2_fxp=511*4194304; | ||
411 | } | ||
412 | |||
413 | //r_u1 = (xcenter + scale*transformed[0]); | ||
414 | r_u1_fxp = xcenter_fxp + scale2_fxp; | ||
415 | if (r_u1_fxp < r_refdef_fvrectx_adj_fxp) | ||
416 | r_u1_fxp = r_refdef_fvrectx_adj_fxp; | ||
417 | if (r_u1_fxp > r_refdef_fvrectright_adj_fxp) | ||
418 | r_u1_fxp = r_refdef_fvrectright_adj_fxp; | ||
419 | |||
420 | //scale = yscale * r_lzi1; | ||
421 | //r_v1 = (ycenter - scale*transformed[1]); | ||
422 | |||
423 | //Dan: Is this needed? | ||
424 | if (!transformed_fxp[2]) scale_fxp=0; | ||
425 | else scale_fxp=yscale_fxp/transformed_fxp[2]; //9.23 / 24.8 = 17.15 | ||
426 | scale2_fxp=transformed_fxp[1]*(scale_fxp); // 23.9 * 17.15 = 9.23 //21.11 | ||
427 | |||
428 | if (transformed_fxp[1]<0) { | ||
429 | if (scale2_fxp>0) scale2_fxp=-511*4194304; | ||
430 | } else { | ||
431 | if (scale2_fxp<0) scale2_fxp=511*4194304; | ||
432 | } | ||
433 | |||
434 | r_v1_fxp = ycenter_fxp - scale2_fxp; | ||
435 | if (r_v1_fxp < r_refdef_fvrecty_adj_fxp) | ||
436 | r_v1_fxp = r_refdef_fvrecty_adj_fxp; | ||
437 | if (r_v1_fxp > r_refdef_fvrectbottom_adj_fxp) | ||
438 | r_v1_fxp = r_refdef_fvrectbottom_adj_fxp; | ||
439 | |||
440 | //if (r_lzi1 > lzi0) | ||
441 | // lzi0 = r_lzi1; | ||
442 | if (r_lzi1_fxp < lzi0_fxp) | ||
443 | lzi0_fxp = r_lzi1_fxp; | ||
444 | |||
445 | //if (lzi0 > r_nearzi) // for mipmap finding | ||
446 | // r_nearzi = lzi0; | ||
447 | if (/*128*/128.0/lzi0_fxp > r_nearzi) { // for mipmap finding | ||
448 | //if (!lzi0_fxp) r_nearzi=0; | ||
449 | //else | ||
450 | r_nearzi = (float)(128.0/lzi0_fxp); | ||
451 | } | ||
452 | |||
453 | // for right edges, all we want is the effect on 1/z | ||
454 | if (r_nearzionly) | ||
455 | return; | ||
456 | |||
457 | r_emitted = 1; | ||
458 | |||
459 | //r_ceilv1 = (int) ceil(r_v1); | ||
460 | r_ceilv1 = r_v1_fxp/4194304; | ||
461 | if (r_v1_fxp&0x3FFFFF) r_ceilv1++; | ||
462 | |||
463 | |||
464 | // create the edge | ||
465 | if (ceilv0 == r_ceilv1) | ||
466 | { | ||
467 | // we cache unclipped horizontal edges as fully clipped | ||
468 | if (cacheoffset != 0x7FFFFFFF) | ||
469 | { | ||
470 | cacheoffset = FULLY_CLIPPED_CACHED | | ||
471 | (r_framecount & FRAMECOUNT_MASK); | ||
472 | } | ||
473 | |||
474 | return; // horizontal edge | ||
475 | } | ||
476 | |||
477 | side = ceilv0 > r_ceilv1; | ||
478 | |||
479 | edge = edge_p++; | ||
480 | |||
481 | edge->owner = NULL; | ||
482 | |||
483 | edge->owner = r_pedge; | ||
484 | |||
485 | //Dan: Is this needed? | ||
486 | if (!lzi0_fxp) edge->nearzi=0.0; | ||
487 | else edge->nearzi = (float)(128.0f/*256.0*//lzi0_fxp); | ||
488 | |||
489 | if (side == 0) | ||
490 | { | ||
491 | int tmp; | ||
492 | // trailing edge (go from p1 to p2) | ||
493 | v = ceilv0; | ||
494 | v2 = r_ceilv1 - 1; | ||
495 | |||
496 | edge->surfs[0] = surface_p - surfaces; | ||
497 | edge->surfs[1] = 0; | ||
498 | |||
499 | //u_step = ((r_u1 - u0) / (r_v1 - v0)); | ||
500 | //u = u0 + ((float)v - v0) * u_step; | ||
501 | |||
502 | tmp=((r_v1_fxp - v0_fxp)>>10); | ||
503 | if (tmp) | ||
504 | u_step_fxp=(r_u1_fxp - u0_fxp) / tmp; //10.22 / 15.12 = 22.10 | ||
505 | else | ||
506 | u_step_fxp=0; | ||
507 | u_fxp = u0_fxp + ((v*4194304 - v0_fxp)>>12 * u_step_fxp>>12); | ||
508 | } | ||
509 | else | ||
510 | { | ||
511 | int tmp; | ||
512 | // leading edge (go from p2 to p1) | ||
513 | v2 = ceilv0 - 1; | ||
514 | v = r_ceilv1; | ||
515 | |||
516 | edge->surfs[0] = 0; | ||
517 | edge->surfs[1] = surface_p - surfaces; | ||
518 | |||
519 | //u_step = ((u0 - r_u1) / (v0 - r_v1)); | ||
520 | //u = r_u1 + ((float)v - r_v1) * u_step; | ||
521 | |||
522 | tmp=((v0_fxp - r_v1_fxp)>>10); | ||
523 | if (tmp) | ||
524 | u_step_fxp = (u0_fxp - r_u1_fxp) / tmp; | ||
525 | else | ||
526 | u_step_fxp=0; | ||
527 | u_fxp = r_u1_fxp + ((v*4194304 - r_v1_fxp)>>12 * u_step_fxp>>12); | ||
528 | |||
529 | } | ||
530 | //edge->u_step = tmp*0x100000; | ||
531 | //edge->u = (int)(/*(u_fxp/65536)*0x100000*/u_fxp/4 + 0xFFFFF); | ||
532 | |||
533 | edge->u_step = u_step_fxp*1024;///16; //tmp*0x100000; | ||
534 | edge->u = (int)(/*(u_fxp/65536)*0x100000*/u_fxp/4 + 0xFFFFF); | ||
535 | |||
536 | // we need to do this to avoid stepping off the edges if a very nearly | ||
537 | // horizontal edge is less than epsilon above a scan, and numeric error causes | ||
538 | // it to incorrectly extend to the scan, and the extension of the line goes off | ||
539 | // the edge of the screen | ||
540 | // FIXME: is this actually needed? | ||
541 | if (edge->u < r_refdef.vrect_x_adj_shift20) | ||
542 | edge->u = r_refdef.vrect_x_adj_shift20; | ||
543 | if (edge->u > r_refdef.vrectright_adj_shift20) | ||
544 | edge->u = r_refdef.vrectright_adj_shift20; | ||
545 | |||
546 | // | ||
547 | // sort the edge in normally | ||
548 | // | ||
549 | u_check = edge->u; | ||
550 | if (edge->surfs[0]) | ||
551 | u_check++; // sort trailers after leaders | ||
552 | |||
553 | if (!newedges[v] || newedges[v]->u >= u_check) | ||
554 | { | ||
555 | edge->next = newedges[v]; | ||
556 | newedges[v] = edge; | ||
557 | } | ||
558 | else | ||
559 | { | ||
560 | pcheck = newedges[v]; | ||
561 | while (pcheck->next && pcheck->next->u < u_check) | ||
562 | pcheck = pcheck->next; | ||
563 | edge->next = pcheck->next; | ||
564 | pcheck->next = edge; | ||
565 | } | ||
566 | |||
567 | edge->nextremove = removeedges[v2]; | ||
568 | removeedges[v2] = edge; | ||
569 | } | ||
570 | #endif | ||
571 | |||
262 | #ifdef USE_PQ_OPT1 | 572 | #ifdef USE_PQ_OPT1 |
263 | void R_EmitEdge_fxp (mvertex_t *pv0, mvertex_t *pv1) | 573 | void R_EmitEdge_fxp (mvertex_t *pv0, mvertex_t *pv1) |
264 | { | 574 | { |
@@ -560,6 +870,138 @@ void R_EmitEdge_fxp (mvertex_t *pv0, mvertex_t *pv1) | |||
560 | } | 870 | } |
561 | #endif | 871 | #endif |
562 | 872 | ||
873 | #ifdef USE_PQ_OPT2 | ||
874 | void R_ClipEdge_fxp (mvertex_fxp_t pv0[3], mvertex_fxp_t pv1[3], clipplane_fxp_t *clip) | ||
875 | { | ||
876 | int d0_fxp, d1_fxp, f_fxp; | ||
877 | mvertex_fxp_t clipvert_fxp; | ||
878 | //12.20 | ||
879 | |||
880 | if (clip) | ||
881 | { | ||
882 | do | ||
883 | { | ||
884 | //13.19 / 20.12 = 25.7 | ||
885 | d0_fxp=(pv0->position[0])/clip->normal[0]+(pv0->position[1])/clip->normal[1]+(pv0->position[2])/clip->normal[2]; | ||
886 | d1_fxp=(pv1->position[0])/clip->normal[0]+(pv1->position[1])/clip->normal[1]+(pv1->position[2])/clip->normal[2]; | ||
887 | d0_fxp-=(clip->dist); | ||
888 | d1_fxp-=(clip->dist); | ||
889 | //d0 = DotProduct (pv0->position, clip->normal) - clip->dist; | ||
890 | //d1 = DotProduct (pv1->position, clip->normal) - clip->dist; | ||
891 | |||
892 | if (d0_fxp >= 0) | ||
893 | { | ||
894 | // point 0 is unclipped | ||
895 | if (d1_fxp >= 0) | ||
896 | { | ||
897 | // both points are unclipped | ||
898 | continue; | ||
899 | } | ||
900 | |||
901 | // only point 1 is clipped | ||
902 | |||
903 | // we don't cache clipped edges | ||
904 | cacheoffset = 0x7FFFFFFF; | ||
905 | |||
906 | if (!(d0_fxp)) | ||
907 | f_fxp=2<<29; | ||
908 | else { | ||
909 | f_fxp = (((d0_fxp - d1_fxp)<<7)/(d0_fxp)); //(25.7->18.14) / 25.7 = 25.7 | ||
910 | if (!f_fxp) f_fxp=2<<29; | ||
911 | } | ||
912 | |||
913 | |||
914 | clipvert_fxp.position[0] = pv0->position[0] + | ||
915 | (((pv1->position[0] - pv0->position[0])/f_fxp)<<7); //13.19 / 25.7 = 20.12 | ||
916 | |||
917 | clipvert_fxp.position[1] = pv0->position[1] + | ||
918 | (((pv1->position[1] - pv0->position[1])/f_fxp)<<7); | ||
919 | |||
920 | clipvert_fxp.position[2] = pv0->position[2] + | ||
921 | (((pv1->position[2] - pv0->position[2])/f_fxp)<<7); | ||
922 | |||
923 | if (clip->leftedge) | ||
924 | { | ||
925 | r_leftclipped = true; | ||
926 | r_leftexit_fxp = clipvert_fxp; | ||
927 | } | ||
928 | else if (clip->rightedge) | ||
929 | { | ||
930 | r_rightclipped = true; | ||
931 | r_rightexit_fxp = clipvert_fxp; | ||
932 | } | ||
933 | |||
934 | R_ClipEdge_fxp (pv0, &clipvert_fxp, clip->next); | ||
935 | return; | ||
936 | } | ||
937 | else | ||
938 | { | ||
939 | // point 0 is clipped | ||
940 | if (d1_fxp < 0) | ||
941 | { | ||
942 | // both points are clipped | ||
943 | // we do cache fully clipped edges | ||
944 | if (!r_leftclipped) | ||
945 | cacheoffset = FULLY_CLIPPED_CACHED | | ||
946 | (r_framecount & FRAMECOUNT_MASK); | ||
947 | return; | ||
948 | } | ||
949 | |||
950 | // only point 0 is clipped | ||
951 | r_lastvertvalid = false; | ||
952 | |||
953 | // we don't cache partially clipped edges | ||
954 | cacheoffset = 0x7FFFFFFF; | ||
955 | |||
956 | if (!d0_fxp) | ||
957 | f_fxp=2<<29; | ||
958 | else { | ||
959 | f_fxp = (((d0_fxp - d1_fxp)<<7)/d0_fxp); //12.20 / 20.12 = 24.8 | ||
960 | if (!f_fxp) f_fxp=2<<29; | ||
961 | } | ||
962 | |||
963 | clipvert_fxp.position[0] = pv0->position[0] + | ||
964 | (((pv1->position[0] - pv0->position[0])/f_fxp)<<7); //12.20 / 24.8 = 20.12 | ||
965 | |||
966 | clipvert_fxp.position[1] = pv0->position[1] + | ||
967 | (((pv1->position[1] - pv0->position[1])/f_fxp)<<7); | ||
968 | |||
969 | clipvert_fxp.position[2] = pv0->position[2] + | ||
970 | (((pv1->position[2] - pv0->position[2])/f_fxp)<<7); | ||
971 | |||
972 | if (clip->leftedge) | ||
973 | { | ||
974 | r_leftclipped = true; | ||
975 | r_leftenter_fxp = clipvert_fxp; | ||
976 | } | ||
977 | else if (clip->rightedge) | ||
978 | { | ||
979 | r_rightclipped = true; | ||
980 | r_rightenter_fxp = clipvert_fxp; | ||
981 | } | ||
982 | |||
983 | R_ClipEdge_fxp (&clipvert_fxp, pv1, clip->next); | ||
984 | return; | ||
985 | } | ||
986 | } while ((clip = clip->next) != NULL); | ||
987 | } | ||
988 | /* | ||
989 | { | ||
990 | mvertex_t p0, p1; | ||
991 | p0.position[0]=pv0->position[0]/524288.0f; | ||
992 | p0.position[1]=pv0->position[1]/524288.0f; | ||
993 | p0.position[2]=pv0->position[2]/524288.0f; | ||
994 | p1.position[0]=pv1->position[0]/524288.0f; | ||
995 | p1.position[1]=pv1->position[1]/524288.0f; | ||
996 | p1.position[2]=pv1->position[2]/524288.0f; | ||
997 | R_EmitEdge (&p0, &p1); | ||
998 | } | ||
999 | */ | ||
1000 | // add the edge | ||
1001 | R_EmitEdgeFXP_fxp (pv0, pv1); | ||
1002 | } | ||
1003 | #endif | ||
1004 | |||
563 | /* | 1005 | /* |
564 | ================ | 1006 | ================ |
565 | R_ClipEdge | 1007 | R_ClipEdge |
@@ -705,6 +1147,9 @@ void R_RenderFace (msurface_t *fa, int clipflags) | |||
705 | vec3_t p_normal; | 1147 | vec3_t p_normal; |
706 | medge_t *pedges, tedge; | 1148 | medge_t *pedges, tedge; |
707 | clipplane_t *pclip; | 1149 | clipplane_t *pclip; |
1150 | #ifdef USE_PQ_OPT2 | ||
1151 | clipplane_fxp_t *pclip_fxp; | ||
1152 | #endif | ||
708 | 1153 | ||
709 | // skip out if no more surfs | 1154 | // skip out if no more surfs |
710 | if ((surface_p) >= surf_max) | 1155 | if ((surface_p) >= surf_max) |
@@ -734,6 +1179,19 @@ void R_RenderFace (msurface_t *fa, int clipflags) | |||
734 | } | 1179 | } |
735 | } | 1180 | } |
736 | 1181 | ||
1182 | #ifdef USE_PQ_OPT2 | ||
1183 | pclip_fxp = NULL; | ||
1184 | |||
1185 | for (i=3, mask = 0x08 ; i>=0 ; i--, mask >>= 1) | ||
1186 | { | ||
1187 | if (clipflags & mask) | ||
1188 | { | ||
1189 | view_clipplanes_fxp[i].next = pclip_fxp; | ||
1190 | pclip_fxp = &view_clipplanes_fxp[i]; | ||
1191 | } | ||
1192 | } | ||
1193 | #endif | ||
1194 | |||
737 | // push the edges through | 1195 | // push the edges through |
738 | r_emitted = 0; | 1196 | r_emitted = 0; |
739 | r_nearzi = 0; | 1197 | r_nearzi = 0; |
@@ -779,9 +1237,16 @@ void R_RenderFace (msurface_t *fa, int clipflags) | |||
779 | // assume it's cacheable | 1237 | // assume it's cacheable |
780 | cacheoffset = (byte *)edge_p - (byte *)r_edges; | 1238 | cacheoffset = (byte *)edge_p - (byte *)r_edges; |
781 | r_leftclipped = r_rightclipped = false; | 1239 | r_leftclipped = r_rightclipped = false; |
1240 | #ifndef USE_PQ_OPT2 | ||
782 | R_ClipEdge (&r_pcurrentvertbase[r_pedge->v[0]], | 1241 | R_ClipEdge (&r_pcurrentvertbase[r_pedge->v[0]], |
783 | &r_pcurrentvertbase[r_pedge->v[1]], | 1242 | &r_pcurrentvertbase[r_pedge->v[1]], |
784 | pclip); | 1243 | pclip); |
1244 | #else | ||
1245 | R_ClipEdge_fxp (&r_pcurrentvertbase_fxp[r_pedge->v[0]], | ||
1246 | &r_pcurrentvertbase_fxp[r_pedge->v[1]], | ||
1247 | pclip_fxp); | ||
1248 | #endif | ||
1249 | |||
785 | r_pedge->cachededgeoffset = cacheoffset; | 1250 | r_pedge->cachededgeoffset = cacheoffset; |
786 | 1251 | ||
787 | if (r_leftclipped) | 1252 | if (r_leftclipped) |
@@ -825,9 +1290,15 @@ void R_RenderFace (msurface_t *fa, int clipflags) | |||
825 | // assume it's cacheable | 1290 | // assume it's cacheable |
826 | cacheoffset = (byte *)edge_p - (byte *)r_edges; | 1291 | cacheoffset = (byte *)edge_p - (byte *)r_edges; |
827 | r_leftclipped = r_rightclipped = false; | 1292 | r_leftclipped = r_rightclipped = false; |
1293 | #ifndef USE_PQ_OPT2 | ||
828 | R_ClipEdge (&r_pcurrentvertbase[r_pedge->v[1]], | 1294 | R_ClipEdge (&r_pcurrentvertbase[r_pedge->v[1]], |
829 | &r_pcurrentvertbase[r_pedge->v[0]], | 1295 | &r_pcurrentvertbase[r_pedge->v[0]], |
830 | pclip); | 1296 | pclip); |
1297 | #else | ||
1298 | R_ClipEdge_fxp (&r_pcurrentvertbase_fxp[r_pedge->v[1]], | ||
1299 | &r_pcurrentvertbase_fxp[r_pedge->v[0]], | ||
1300 | pclip_fxp); | ||
1301 | #endif | ||
831 | r_pedge->cachededgeoffset = cacheoffset; | 1302 | r_pedge->cachededgeoffset = cacheoffset; |
832 | 1303 | ||
833 | if (r_leftclipped) | 1304 | if (r_leftclipped) |
@@ -845,7 +1316,11 @@ void R_RenderFace (msurface_t *fa, int clipflags) | |||
845 | { | 1316 | { |
846 | r_pedge = &tedge; | 1317 | r_pedge = &tedge; |
847 | r_lastvertvalid = false; | 1318 | r_lastvertvalid = false; |
1319 | #ifndef USE_PQ_OPT2 | ||
848 | R_ClipEdge (&r_leftexit, &r_leftenter, pclip->next); | 1320 | R_ClipEdge (&r_leftexit, &r_leftenter, pclip->next); |
1321 | #else | ||
1322 | R_ClipEdge_fxp (&r_leftexit_fxp, &r_leftenter_fxp, pclip_fxp->next); | ||
1323 | #endif | ||
849 | } | 1324 | } |
850 | 1325 | ||
851 | // if there was a clip off the right edge, get the right r_nearzi | 1326 | // if there was a clip off the right edge, get the right r_nearzi |
@@ -854,7 +1329,11 @@ void R_RenderFace (msurface_t *fa, int clipflags) | |||
854 | r_pedge = &tedge; | 1329 | r_pedge = &tedge; |
855 | r_lastvertvalid = false; | 1330 | r_lastvertvalid = false; |
856 | r_nearzionly = true; | 1331 | r_nearzionly = true; |
1332 | #ifndef USE_PQ_OPT2 | ||
857 | R_ClipEdge (&r_rightexit, &r_rightenter, view_clipplanes[1].next); | 1333 | R_ClipEdge (&r_rightexit, &r_rightenter, view_clipplanes[1].next); |
1334 | #else | ||
1335 | R_ClipEdge_fxp (&r_rightexit_fxp, &r_rightenter_fxp, view_clipplanes_fxp[1].next); | ||
1336 | #endif | ||
858 | } | 1337 | } |
859 | 1338 | ||
860 | // if no edges made it out, return without posting the surface | 1339 | // if no edges made it out, return without posting the surface |
@@ -876,14 +1355,22 @@ void R_RenderFace (msurface_t *fa, int clipflags) | |||
876 | // FIXME: cache this? | 1355 | // FIXME: cache this? |
877 | TransformVector (pplane->normal, p_normal); | 1356 | TransformVector (pplane->normal, p_normal); |
878 | // FIXME: cache this? | 1357 | // FIXME: cache this? |
879 | distinv = 1.0 / (pplane->dist - DotProduct (modelorg, pplane->normal)); | 1358 | distinv = (float) 1.0 / (pplane->dist - DotProduct (modelorg, pplane->normal)); |
880 | 1359 | ||
1360 | #ifndef USE_PQ_OPT3 | ||
881 | surface_p->d_zistepu = p_normal[0] * xscaleinv * distinv; | 1361 | surface_p->d_zistepu = p_normal[0] * xscaleinv * distinv; |
882 | surface_p->d_zistepv = -p_normal[1] * yscaleinv * distinv; | 1362 | surface_p->d_zistepv = -p_normal[1] * yscaleinv * distinv; |
883 | surface_p->d_ziorigin = p_normal[2] * distinv - | 1363 | surface_p->d_ziorigin = p_normal[2] * distinv - |
884 | xcenter * surface_p->d_zistepu - | 1364 | xcenter * surface_p->d_zistepu - |
885 | ycenter * surface_p->d_zistepv; | 1365 | ycenter * surface_p->d_zistepv; |
886 | 1366 | #else | |
1367 | surface_p->d_zistepu_fxp=(int)(p_normal[0] * xscaleinv * distinv*4194304.0f); | ||
1368 | surface_p->d_zistepv_fxp=(int)(-p_normal[1] * yscaleinv * distinv*4194304.0f); | ||
1369 | surface_p->d_ziorigin_fxp=((int)(p_normal[2] * distinv * 4194304.0f)) - | ||
1370 | ((int)(xcenter * surface_p->d_zistepu_fxp)) - | ||
1371 | ((int)(ycenter * surface_p->d_zistepv_fxp)); | ||
1372 | #endif | ||
1373 | |||
887 | //JDC VectorCopy (r_worldmodelorg, surface_p->modelorg); | 1374 | //JDC VectorCopy (r_worldmodelorg, surface_p->modelorg); |
888 | surface_p++; | 1375 | surface_p++; |
889 | } | 1376 | } |
diff --git a/apps/plugins/sdl/progs/quake/r_local.h b/apps/plugins/sdl/progs/quake/r_local.h index ae3416ba2f..adb9565b8b 100644 --- a/apps/plugins/sdl/progs/quake/r_local.h +++ b/apps/plugins/sdl/progs/quake/r_local.h | |||
@@ -94,7 +94,28 @@ typedef struct clipplane_s | |||
94 | byte reserved[2]; | 94 | byte reserved[2]; |
95 | } clipplane_t; | 95 | } clipplane_t; |
96 | 96 | ||
97 | typedef struct clipplane_fxp_s | ||
98 | { | ||
99 | int normal[3]; | ||
100 | int dist; | ||
101 | struct clipplane_fxp_s *next; | ||
102 | byte leftedge; | ||
103 | byte rightedge; | ||
104 | byte reserved[2]; | ||
105 | } clipplane_fxp_t; | ||
106 | |||
107 | typedef struct clipplane_FPM_s | ||
108 | { | ||
109 | vec3_FPM_t normal; | ||
110 | fixedpoint_t dist; | ||
111 | struct clipplane_FPM_s *next; | ||
112 | byte leftedge; | ||
113 | byte rightedge; | ||
114 | byte reserved[2]; | ||
115 | } clipplane_FPM_t; | ||
116 | |||
97 | extern clipplane_t view_clipplanes[4]; | 117 | extern clipplane_t view_clipplanes[4]; |
118 | extern clipplane_FPM_t view_clipplanesFPM[4]; | ||
98 | 119 | ||
99 | #ifdef USE_PQ_OPT2 | 120 | #ifdef USE_PQ_OPT2 |
100 | extern clipplane_fxp_t view_clipplanes_fxp[4]; | 121 | extern clipplane_fxp_t view_clipplanes_fxp[4]; |
diff --git a/apps/plugins/sdl/progs/quake/r_main.c b/apps/plugins/sdl/progs/quake/r_main.c index 7776b46bde..4aa14d69da 100644 --- a/apps/plugins/sdl/progs/quake/r_main.c +++ b/apps/plugins/sdl/progs/quake/r_main.c | |||
@@ -43,6 +43,9 @@ qboolean r_dowarp, r_dowarpold, r_viewchanged; | |||
43 | int numbtofpolys; | 43 | int numbtofpolys; |
44 | btofpoly_t *pbtofpolys; | 44 | btofpoly_t *pbtofpolys; |
45 | mvertex_t *r_pcurrentvertbase; | 45 | mvertex_t *r_pcurrentvertbase; |
46 | #ifdef USE_PQ_OPT2 | ||
47 | mvertex_fxp_t *r_pcurrentvertbase_fxp; | ||
48 | #endif | ||
46 | 49 | ||
47 | int c_surf; | 50 | int c_surf; |
48 | int r_maxsurfsseen, r_maxedgesseen, r_cnumsurfs; | 51 | int r_maxsurfsseen, r_maxedgesseen, r_cnumsurfs; |
@@ -808,6 +811,10 @@ void R_DrawBEntitiesOnList (void) | |||
808 | VectorCopy (modelorg, r_worldmodelorg); | 811 | VectorCopy (modelorg, r_worldmodelorg); |
809 | 812 | ||
810 | r_pcurrentvertbase = clmodel->vertexes; | 813 | r_pcurrentvertbase = clmodel->vertexes; |
814 | |||
815 | #ifdef USE_PQ_OPT2 | ||
816 | r_pcurrentvertbase_fxp = clmodel->vertexes_fxp; | ||
817 | #endif | ||
811 | 818 | ||
812 | // FIXME: stop transforming twice | 819 | // FIXME: stop transforming twice |
813 | R_RotateBmodel (); | 820 | R_RotateBmodel (); |
diff --git a/apps/plugins/sdl/progs/quake/r_misc.c b/apps/plugins/sdl/progs/quake/r_misc.c index c0aa7e991d..349f760140 100644 --- a/apps/plugins/sdl/progs/quake/r_misc.c +++ b/apps/plugins/sdl/progs/quake/r_misc.c | |||
@@ -286,8 +286,18 @@ void R_TransformFrustum (void) | |||
286 | v2[2] = v[1]*vright[2] + v[2]*vup[2] + v[0]*vpn[2]; | 286 | v2[2] = v[1]*vright[2] + v[2]*vup[2] + v[0]*vpn[2]; |
287 | 287 | ||
288 | VectorCopy (v2, view_clipplanes[i].normal); | 288 | VectorCopy (v2, view_clipplanes[i].normal); |
289 | |||
290 | view_clipplanes[i].dist = DotProduct (modelorg, v2); | 289 | view_clipplanes[i].dist = DotProduct (modelorg, v2); |
290 | |||
291 | #ifdef USE_PQ_OPT2 | ||
292 | if (!v2[0]) view_clipplanes_fxp[i].normal[0]=2<29; | ||
293 | else view_clipplanes_fxp[i].normal[0]=(int)(4096.0f/v2[0]); | ||
294 | if (!v2[1]) view_clipplanes_fxp[i].normal[1]=2<29; | ||
295 | else view_clipplanes_fxp[i].normal[1]=(int)(4096.0f/v2[1]); | ||
296 | if (!v2[2]) view_clipplanes_fxp[i].normal[2]=2<29; | ||
297 | else view_clipplanes_fxp[i].normal[2]=(int)(4096.0f/v2[2]); | ||
298 | |||
299 | view_clipplanes_fxp[i].dist=(int)(view_clipplanes[i].dist*128.0); | ||
300 | #endif | ||
291 | } | 301 | } |
292 | } | 302 | } |
293 | 303 | ||
@@ -306,6 +316,38 @@ void TransformVector (vec3_t in, vec3_t out) | |||
306 | out[2] = DotProduct(in,vpn); | 316 | out[2] = DotProduct(in,vpn); |
307 | } | 317 | } |
308 | 318 | ||
319 | #ifdef USE_PQ_OPT | ||
320 | //JB: Optimization | ||
321 | static float last; | ||
322 | static fpvec3 fpvright, fpvup, fpvpn; | ||
323 | void FPTransformVector( fpvec3 in, fpvec3 out ) | ||
324 | { | ||
325 | if (last != vright[0]) | ||
326 | { | ||
327 | last = vright[0]; | ||
328 | fpvright[0] = (int)(16384.0f * vright[0]); | ||
329 | fpvright[1] = (int)(16384.0f * vright[1]); | ||
330 | fpvright[2] = (int)(16384.0f * vright[2]); | ||
331 | fpvup[0] = (int)(16384.0f * vup[0]); | ||
332 | fpvup[1] = (int)(16384.0f * vup[1]); | ||
333 | fpvup[2] = (int)(16384.0f * vup[2]); | ||
334 | fpvpn[0] = (int)(16384.0f * vpn[0]); | ||
335 | fpvpn[1] = (int)(16384.0f * vpn[1]); | ||
336 | fpvpn[2] = (int)(16384.0f * vpn[2]); | ||
337 | } | ||
338 | out[0] = (in[0] * fpvright[0] + | ||
339 | in[1] * fpvright[1] + | ||
340 | in[2] * fpvright[2]) >> 4; | ||
341 | out[1] = (in[0] * fpvup[0] + | ||
342 | in[1] * fpvup[1] + | ||
343 | in[2] * fpvup[2]) >> 4; | ||
344 | out[2] = (in[0] * fpvpn[0] + | ||
345 | in[1] * fpvpn[1] + | ||
346 | in[2] * fpvpn[2]) >> 4; | ||
347 | } | ||
348 | |||
349 | #endif | ||
350 | |||
309 | #endif | 351 | #endif |
310 | 352 | ||
311 | 353 | ||