d_sky.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  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. // d_sky.c
  16. #include "quakedef.h"
  17. #include "r_local.h"
  18. #include "d_local.h"
  19. #define SKY_SPAN_SHIFT 5
  20. #define SKY_SPAN_MAX (1 << SKY_SPAN_SHIFT)
  21. /*
  22. =================
  23. D_Sky_uv_To_st
  24. =================
  25. */
  26. void D_Sky_uv_To_st (int u, int v, fixed16_t *s, fixed16_t *t)
  27. {
  28. float wu, wv, temp;
  29. vec3_t end;
  30. if (r_refdef.vrect.width >= r_refdef.vrect.height)
  31. temp = (float)r_refdef.vrect.width;
  32. else
  33. temp = (float)r_refdef.vrect.height;
  34. wu = 8192.0 * (float)(u-((int)vid.width>>1)) / temp;
  35. wv = 8192.0 * (float)(((int)vid.height>>1)-v) / temp;
  36. end[0] = 4096*vpn[0] + wu*vright[0] + wv*vup[0];
  37. end[1] = 4096*vpn[1] + wu*vright[1] + wv*vup[1];
  38. end[2] = 4096*vpn[2] + wu*vright[2] + wv*vup[2];
  39. end[2] *= 3;
  40. VectorNormalize (end);
  41. temp = skytime*skyspeed; // TODO: add D_SetupFrame & set this there
  42. *s = (int)((temp + 6*(SKYSIZE/2-1)*end[0]) * 0x10000);
  43. *t = (int)((temp + 6*(SKYSIZE/2-1)*end[1]) * 0x10000);
  44. }
  45. /*
  46. =================
  47. D_DrawSkyScans8
  48. =================
  49. */
  50. void D_DrawSkyScans8 (espan_t *pspan)
  51. {
  52. int count, spancount, u, v;
  53. unsigned char *pdest;
  54. fixed16_t s, t, snext, tnext, sstep, tstep;
  55. int spancountminus1;
  56. sstep = 0; // keep compiler happy
  57. tstep = 0; // ditto
  58. do
  59. {
  60. pdest = (unsigned char *)((byte *)d_viewbuffer +
  61. (screenwidth * pspan->v) + pspan->u);
  62. count = pspan->count;
  63. // calculate the initial s & t
  64. u = pspan->u;
  65. v = pspan->v;
  66. D_Sky_uv_To_st (u, v, &s, &t);
  67. do
  68. {
  69. if (count >= SKY_SPAN_MAX)
  70. spancount = SKY_SPAN_MAX;
  71. else
  72. spancount = count;
  73. count -= spancount;
  74. if (count)
  75. {
  76. u += spancount;
  77. // calculate s and t at far end of span,
  78. // calculate s and t steps across span by shifting
  79. D_Sky_uv_To_st (u, v, &snext, &tnext);
  80. sstep = (snext - s) >> SKY_SPAN_SHIFT;
  81. tstep = (tnext - t) >> SKY_SPAN_SHIFT;
  82. }
  83. else
  84. {
  85. // calculate s and t at last pixel in span,
  86. // calculate s and t steps across span by division
  87. spancountminus1 = (float)(spancount - 1);
  88. if (spancountminus1 > 0)
  89. {
  90. u += spancountminus1;
  91. D_Sky_uv_To_st (u, v, &snext, &tnext);
  92. sstep = (snext - s) / spancountminus1;
  93. tstep = (tnext - t) / spancountminus1;
  94. }
  95. }
  96. do
  97. {
  98. *pdest++ = r_skysource[((t & R_SKY_TMASK) >> 8) +
  99. ((s & R_SKY_SMASK) >> 16)];
  100. s += sstep;
  101. t += tstep;
  102. } while (--spancount > 0);
  103. s = snext;
  104. t = tnext;
  105. } while (count > 0);
  106. } while ((pspan = pspan->pnext) != NULL);
  107. }