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-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
14 #pragma off (unreferenced)
15 static char rcsid[] = "$Id: terrain.c,v 1.1.1.1 2001-01-19 03:30:14 bradleyb Exp $";
16 #pragma on (unreferenced)
36 #define GRID_MAX_SIZE 64
37 #define GRID_SCALE i2f(2*20)
38 #define HEIGHT_SCALE f1_0
42 g3s_uvl uvl_list1[] = { {0,0,0}, {f1_0,0,0}, {0,f1_0,0} };
43 g3s_uvl uvl_list2[] = { {f1_0,0,0}, {f1_0,f1_0,0}, {0,f1_0,0} };
48 #define HEIGHT(_i,_j) (height_array[(_i)*grid_w+(_j)])
49 #define LIGHT(_i,_j) light_array[(_i)*grid_w+(_j)]
51 //!!#define HEIGHT(_i,_j) height_array[(grid_h-1-j)*grid_w+(_i)]
52 //!!#define LIGHT(_i,_j) light_array[(grid_h-1-j)*grid_w+(_i)]
54 #define LIGHTVAL(_i,_j) (((fix) LIGHT(_i,_j))<<8)
56 g3s_point save_row[GRID_MAX_SIZE];
58 vms_vector start_point;
60 grs_bitmap *terrain_bm;
62 extern fix g3_get_surface_dotprod(g3s_point **list);
63 #pragma aux g3_get_surface_dotprod "*" parm [esi] value [eax] modify exact [eax];
65 int terrain_outline=0;
67 void render_mine(int start_seg_num,fix eye_offset);
71 int mine_tiles_drawn; //flags to tell if all 4 tiles under mine have drawn
74 // LINT: adding function prototypes
75 void build_light_table(void);
76 void free_light_table(void);
79 // ------------------------------------------------------------------------
80 void draw_cell(int i,int j,g3s_point *p0,g3s_point *p1,g3s_point *p2,g3s_point *p3)
82 g3s_point *pointlist[3];
87 uvl_list1[0].l = LIGHTVAL(i,j);
88 uvl_list1[1].l = LIGHTVAL(i,j+1);
89 uvl_list1[2].l = LIGHTVAL(i+1,j);
91 uvl_list1[0].u = (i)*f1_0/4; uvl_list1[0].v = (j)*f1_0/4;
92 uvl_list1[1].u = (i)*f1_0/4; uvl_list1[1].v = (j+1)*f1_0/4;
93 uvl_list1[2].u = (i+1)*f1_0/4; uvl_list1[2].v = (j)*f1_0/4;
95 g3_check_and_draw_tmap(3,pointlist,uvl_list1,terrain_bm,NULL,NULL);
96 if (terrain_outline) {
97 int lsave=Lighting_on;
99 gr_setcolor(BM_XRGB(31,0,0));
100 g3_draw_line(pointlist[0],pointlist[1]);
101 g3_draw_line(pointlist[2],pointlist[0]);
107 uvl_list2[0].l = LIGHTVAL(i,j+1);
108 uvl_list2[1].l = LIGHTVAL(i+1,j+1);
109 uvl_list2[2].l = LIGHTVAL(i+1,j);
111 uvl_list2[0].u = (i)*f1_0/4; uvl_list2[0].v = (j+1)*f1_0/4;
112 uvl_list2[1].u = (i+1)*f1_0/4; uvl_list2[1].v = (j+1)*f1_0/4;
113 uvl_list2[2].u = (i+1)*f1_0/4; uvl_list2[2].v = (j)*f1_0/4;
115 g3_check_and_draw_tmap(3,pointlist,uvl_list2,terrain_bm,NULL,NULL);
116 if (terrain_outline) {
117 int lsave=Lighting_on;
119 gr_setcolor(BM_XRGB(31,0,0));
120 g3_draw_line(pointlist[0],pointlist[1]);
121 g3_draw_line(pointlist[1],pointlist[2]);
122 g3_draw_line(pointlist[2],pointlist[0]);
126 if (i==org_i && j==org_j)
127 mine_tiles_drawn |= 1;
128 if (i==org_i-1 && j==org_j)
129 mine_tiles_drawn |= 2;
130 if (i==org_i && j==org_j-1)
131 mine_tiles_drawn |= 4;
132 if (i==org_i-1 && j==org_j-1)
133 mine_tiles_drawn |= 8;
135 if (mine_tiles_drawn == 0xf) {
136 render_mine(exit_segnum,0);
139 //if (ext_expl_playing)
140 // draw_fireball(&external_explosion);
145 vms_vector y_cache[256];
148 extern vms_matrix surface_orient;
150 vms_vector *get_dy_vec(int h)
159 //@@g3_rotate_delta_y(dyp,h*HEIGHT_SCALE);
161 vm_vec_copy_scale(&tv,&surface_orient.uvec,h*HEIGHT_SCALE);
162 g3_rotate_delta_vec(dyp,&tv);
173 void render_terrain(vms_vector *org_point,int org_2dx,int org_2dy)
175 vms_vector delta_i,delta_j; //delta_y;
176 g3s_point p,last_p,save_p_low,save_p_high;
179 int low_i,high_i,low_j,high_j;
180 int viewer_i,viewer_j;
183 mine_tiles_drawn = 0; //clear flags
188 low_i = 0; high_i = grid_w-1;
189 low_j = 0; high_j = grid_h-1;
191 //@@start_point.x = org_point->x - GRID_SCALE*(org_i - low_i);
192 //@@start_point.z = org_point->z - GRID_SCALE*(org_j - low_j);
193 //@@start_point.y = org_point->y;
195 memset(yc_flags,0,256);
198 Interpolation_method = im;
200 vm_vec_copy_scale(&tv,&surface_orient.rvec,GRID_SCALE);
201 g3_rotate_delta_vec(&delta_i,&tv);
202 vm_vec_copy_scale(&tv,&surface_orient.fvec,GRID_SCALE);
203 g3_rotate_delta_vec(&delta_j,&tv);
205 vm_vec_scale_add(&start_point,org_point,&surface_orient.rvec,-(org_i - low_i)*GRID_SCALE);
206 vm_vec_scale_add2(&start_point,&surface_orient.fvec,-(org_j - low_j)*GRID_SCALE);
208 vm_vec_sub(&tv,&Viewer->pos,&start_point);
209 viewer_i = vm_vec_dot(&tv,&surface_orient.rvec) / GRID_SCALE;
210 viewer_j = vm_vec_dot(&tv,&surface_orient.fvec) / GRID_SCALE;
212 //mprintf((0,"viewer_i,j = %d,%d\n",viewer_i,viewer_j));
214 g3_rotate_point(&last_p,&start_point);
217 for (j=low_j;j<=high_j;j++) {
218 g3_add_delta_vec(&save_row[j],&last_p,get_dy_vec(HEIGHT(low_i,j)));
220 save_p_high = last_p;
222 g3_add_delta_vec(&last_p,&last_p,&delta_j);
225 for (i=low_i;i<viewer_i;i++) {
227 g3_add_delta_vec(&save_p_low,&save_p_low,&delta_i);
229 g3_add_delta_vec(&last_p2,&last_p,get_dy_vec(HEIGHT(i+1,low_j)));
231 for (j=low_j;j<viewer_j;j++) {
234 g3_add_delta_vec(&p,&last_p,&delta_j);
235 g3_add_delta_vec(&p2,&p,get_dy_vec(HEIGHT(i+1,j+1)));
237 draw_cell(i,j,&save_row[j],&save_row[j+1],&p2,&last_p2);
240 save_row[j] = last_p2;
245 vm_vec_negate(&delta_j); //don't have a delta sub...
247 g3_add_delta_vec(&save_p_high,&save_p_high,&delta_i);
248 last_p = save_p_high;
249 g3_add_delta_vec(&last_p2,&last_p,get_dy_vec(HEIGHT(i+1,high_j)));
251 for (j=high_j-1;j>=viewer_j;j--) {
254 g3_add_delta_vec(&p,&last_p,&delta_j);
255 g3_add_delta_vec(&p2,&p,get_dy_vec(HEIGHT(i+1,j)));
257 draw_cell(i,j,&save_row[j],&save_row[j+1],&last_p2,&p2);
260 save_row[j+1] = last_p2;
265 save_row[j+1] = last_p2;
267 vm_vec_negate(&delta_j); //restore sign of j
271 //now do i from other end
273 vm_vec_negate(&delta_i); //going the other way now...
275 //@@start_point.x += (high_i-low_i)*GRID_SCALE;
276 vm_vec_scale_add2(&start_point,&surface_orient.rvec,(high_i-low_i)*GRID_SCALE);
277 g3_rotate_point(&last_p,&start_point);
280 for (j=low_j;j<=high_j;j++) {
281 g3_add_delta_vec(&save_row[j],&last_p,get_dy_vec(HEIGHT(high_i,j)));
283 save_p_high = last_p;
285 g3_add_delta_vec(&last_p,&last_p,&delta_j);
288 for (i=high_i-1;i>=viewer_i;i--) {
290 g3_add_delta_vec(&save_p_low,&save_p_low,&delta_i);
292 g3_add_delta_vec(&last_p2,&last_p,get_dy_vec(HEIGHT(i,low_j)));
294 for (j=low_j;j<viewer_j;j++) {
297 g3_add_delta_vec(&p,&last_p,&delta_j);
298 g3_add_delta_vec(&p2,&p,get_dy_vec(HEIGHT(i,j+1)));
300 draw_cell(i,j,&last_p2,&p2,&save_row[j+1],&save_row[j]);
303 save_row[j] = last_p2;
308 vm_vec_negate(&delta_j); //don't have a delta sub...
310 g3_add_delta_vec(&save_p_high,&save_p_high,&delta_i);
311 last_p = save_p_high;
312 g3_add_delta_vec(&last_p2,&last_p,get_dy_vec(HEIGHT(i,high_j)));
314 for (j=high_j-1;j>=viewer_j;j--) {
317 g3_add_delta_vec(&p,&last_p,&delta_j);
318 g3_add_delta_vec(&p2,&p,get_dy_vec(HEIGHT(i,j)));
320 draw_cell(i,j,&p2,&last_p2,&save_row[j+1],&save_row[j]);
323 save_row[j+1] = last_p2;
328 save_row[j+1] = last_p2;
330 vm_vec_negate(&delta_j); //restore sign of j
336 void free_height_array()
341 void load_terrain(char *filename)
343 grs_bitmap height_bitmap;
348 iff_error = iff_read_bitmap(filename,&height_bitmap,BM_LINEAR,NULL);
349 if (iff_error != IFF_NO_ERROR) {
350 mprintf((1, "File %s - IFF error: %s",filename,iff_errormsg(iff_error)));
351 Error("File %s - IFF error: %s",filename,iff_errormsg(iff_error));
357 atexit(free_height_array); //first time
359 grid_w = height_bitmap.bm_w;
360 grid_h = height_bitmap.bm_h;
362 Assert(grid_w <= GRID_MAX_SIZE);
363 Assert(grid_h <= GRID_MAX_SIZE);
365 height_array = height_bitmap.bm_data;
368 for (i=0;i<grid_w;i++)
369 for (j=0;j<grid_h;j++) {
380 for (i=0;i<grid_w;i++)
381 for (j=0;j<grid_h;j++)
382 HEIGHT(i,j) -= min_h;
385 // free(height_bitmap.bm_data);
387 terrain_bm = terrain_bitmap;
393 void get_pnt(vms_vector *p,int i,int j)
397 p->y = HEIGHT(i,j)*HEIGHT_SCALE;
400 vms_vector light = {0x2e14,0xe8f5,0x5eb8};
402 fix get_face_light(vms_vector *p0,vms_vector *p1,vms_vector *p2)
406 vm_vec_normal(&norm,p0,p1,p2);
408 return -vm_vec_dot(&norm,&light);
413 fix get_avg_light(int i,int j)
420 get_pnt(&p[0],i-1,j);
421 get_pnt(&p[1],i,j-1);
422 get_pnt(&p[2],i+1,j-1);
423 get_pnt(&p[3],i+1,j);
424 get_pnt(&p[4],i,j+1);
425 get_pnt(&p[5],i-1,j+1);
427 for (f=0,sum=0;f<6;f++)
428 sum += get_face_light(&pp,&p[f],&p[(f+1)%5]);
433 void free_light_table()
440 void build_light_table()
443 fix l,l2,min_l=0x7fffffff,max_l=0;
449 atexit(free_light_table); //first time
451 MALLOC(light_array,ubyte,grid_w*grid_h);
453 for (i=1;i<grid_w;i++)
454 for (j=1;j<grid_h;j++) {
455 l = get_avg_light(i,j);
463 //printf("light %2d,%2d = %8x\n",i,j,l);
466 for (i=1;i<grid_w;i++)
467 for (j=1;j<grid_h;j++) {
469 l = get_avg_light(i,j);
471 if (min_l == max_l) {
476 l2 = fixdiv((l-min_l),(max_l-min_l));
483 //printf("light %2d,%2d = %4x\n",i,j,l2>>8);