TMAPSKY.C 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. /*
  2. THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
  3. SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
  4. END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
  5. ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
  6. IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
  7. SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
  8. FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
  9. CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
  10. AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
  11. COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
  12. */
  13. /*
  14. * $Source: f:/miner/source/texmap/rcs/tmapsky.c $
  15. * $Revision: 1.4 $
  16. * $Author: mike $
  17. * $Date: 1994/11/28 13:34:33 $
  18. *
  19. * Sky texture mapper for Sim City 2000 Drive Through
  20. *
  21. * $Log: tmapsky.c $
  22. * Revision 1.4 1994/11/28 13:34:33 mike
  23. * optimizations.
  24. *
  25. * Revision 1.3 1994/06/09 16:10:10 mike
  26. * Kill definition of SC2000.
  27. *
  28. * Revision 1.2 1994/03/15 14:49:58 mike
  29. * *** empty log message ***
  30. *
  31. * Revision 1.1 1994/03/15 10:30:53 mike
  32. * Initial revision
  33. *
  34. *
  35. */
  36. #pragma off (unreferenced)
  37. static char rcsid[] = "$Id: tmapsky.c 1.4 1994/11/28 13:34:33 mike Exp $";
  38. #pragma on (unreferenced)
  39. // This is evil and it's all Matt's fault, and it is only here so Assert will work, but that
  40. // should work off ifdef, not if, so there!
  41. #define DEBUG_ON 1
  42. #include <math.h>
  43. #include <limits.h>
  44. #include <stdio.h>
  45. #include <conio.h>
  46. #include <stdlib.h>
  47. #include "mono.h"
  48. #include "fix.h"
  49. #include "3d.h"
  50. #include "gr.h"
  51. #include "error.h"
  52. #include "texmap.h"
  53. #include "texmapl.h"
  54. #define F15_5 (F1_0*15 + F0_5)
  55. int Do_sky_vertical = 0;
  56. void tmap_scanline_lin_sky(grs_bitmap *srcb, int y, fix xleft, fix xright, fix uleft, fix uright, fix vleft, fix vright)
  57. {
  58. fix u,v;
  59. fix dx;
  60. u = uleft;
  61. v = vleft;
  62. dx = xright - xleft;
  63. if (dx < 0)
  64. return;
  65. // setup to call assembler scanline renderer
  66. fx_u = uleft;
  67. fx_v = vleft;
  68. if (dx < f1_0) {
  69. fx_du_dx = uright-uleft;
  70. fx_dv_dx = vright-vleft;
  71. } else {
  72. fx_du_dx = fixdiv(uright - fx_u,dx);
  73. fx_dv_dx = fixdiv(vright - fx_v,dx);
  74. }
  75. fx_y = y;
  76. fx_xleft = xleft;
  77. fx_xright = xright;
  78. pixptr = srcb->bm_data;
  79. asm_tmap_scanline_lin_sky();
  80. }
  81. // -------------------------------------------------------------------------------------
  82. // Render a texture map.
  83. // Linear in outer loop, linear in inner loop.
  84. // -------------------------------------------------------------------------------------
  85. void texture_map_lin_lin_sky(grs_bitmap *srcb, g3ds_tmap *t)
  86. {
  87. int vlt,vrt,vlb,vrb; // vertex left top, vertex right top, vertex left bottom, vertex right bottom
  88. int topy,boty,y;
  89. int left_break,right_break;
  90. fix dx_dy_left,dx_dy_right;
  91. fix du_dy_left,du_dy_right;
  92. fix dv_dy_left,dv_dy_right;
  93. int max_y_vertex;
  94. fix xleft,xright,uleft,vleft,uright,vright;
  95. g3ds_vertex *v3d;
  96. if (Do_sky_vertical) {
  97. texture_map_lin_lin_sky_v(srcb, t);
  98. return;
  99. }
  100. //--now called from g3_start_frame-- init_interface_vars_to_assembler();
  101. v3d = t->verts;
  102. // Determine top and bottom y coords.
  103. compute_y_bounds(t,&vlt,&vlb,&vrt,&vrb,&max_y_vertex);
  104. // Set top and bottom (of entire texture map) y coordinates.
  105. topy = f2i(v3d[vlt].y2d);
  106. boty = f2i(v3d[max_y_vertex].y2d);
  107. // Set amount to change x coordinate for each advance to next scanline.
  108. dx_dy_left = compute_dx_dy_lin(t,vlt,vlb);
  109. dx_dy_right = compute_dx_dy_lin(t,vrt,vrb);
  110. du_dy_left = compute_du_dy_lin(t,vlt,vlb);
  111. du_dy_right = compute_du_dy_lin(t,vrt,vrb);
  112. dv_dy_left = compute_dv_dy_lin(t,vlt,vlb);
  113. dv_dy_right = compute_dv_dy_lin(t,vrt,vrb);
  114. // Set initial values for x, u, v
  115. xleft = v3d[vlt].x2d;
  116. xright = v3d[vrt].x2d;
  117. uleft = v3d[vlt].u;
  118. uright = v3d[vrt].u;
  119. vleft = v3d[vlt].v;
  120. vright = v3d[vrt].v;
  121. // scan all rows in texture map from top through first break.
  122. // @mk: Should we render the scanline for y==boty? This violates Matt's spec.
  123. left_break = f2i(v3d[vlb].y2d);
  124. right_break = f2i(v3d[vrb].y2d);
  125. for (y = topy; y < boty; y++) {
  126. // See if we have reached the end of the current left edge, and if so, set
  127. // new values for dx_dy and x,u,v
  128. if (y == left_break) {
  129. // Handle problem of double points. Search until y coord is different. Cannot get
  130. // hung in an infinite loop because we know there is a vertex with a lower y coordinate
  131. // because in the for loop, we don't scan all spanlines.
  132. while (y == f2i(v3d[vlb].y2d)) {
  133. vlt = vlb;
  134. vlb = prevmod(vlb,t->nv);
  135. }
  136. left_break = f2i(v3d[vlb].y2d);
  137. dx_dy_left = compute_dx_dy_lin(t,vlt,vlb);
  138. xleft = v3d[vlt].x2d;
  139. uleft = v3d[vlt].u;
  140. vleft = v3d[vlt].v;
  141. du_dy_left = compute_du_dy_lin(t,vlt,vlb);
  142. dv_dy_left = compute_dv_dy_lin(t,vlt,vlb);
  143. }
  144. // See if we have reached the end of the current left edge, and if so, set
  145. // new values for dx_dy and x. Not necessary to set new values for u,v.
  146. if (y == right_break) {
  147. while (y == f2i(v3d[vrb].y2d)) {
  148. vrt = vrb;
  149. vrb = succmod(vrb,t->nv);
  150. }
  151. right_break = f2i(v3d[vrb].y2d);
  152. dx_dy_right = compute_dx_dy_lin(t,vrt,vrb);
  153. xright = v3d[vrt].x2d;
  154. uright = v3d[vrt].u;
  155. vright = v3d[vrt].v;
  156. du_dy_right = compute_du_dy_lin(t,vrt,vrb);
  157. dv_dy_right = compute_dv_dy_lin(t,vrt,vrb);
  158. }
  159. tmap_scanline_lin_sky(srcb,y,xleft,xright,uleft,uright,vleft,vright);
  160. uleft += du_dy_left;
  161. vleft += dv_dy_left;
  162. uright += du_dy_right;
  163. vright += dv_dy_right;
  164. xleft += dx_dy_left;
  165. xright += dx_dy_right;
  166. }
  167. tmap_scanline_lin_sky(srcb,y,xleft,xright,uleft,uright,vleft,vright);
  168. }