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.
14 * $Source: /cvs/cvsroot/d2x/3d/interp.c,v $
17 * $Date: 2001-10-31 03:54:50 $
19 * Polygon object interpreter
21 * $Log: not supported by cvs2svn $
22 * Revision 1.3 2001/10/19 08:06:20 bradleyb
23 * Partial application of linux/alpha patch. Courtesy of Falk Hueffner <falk.hueffner@student.uni-tuebingen.de>
25 * Revision 1.2 2001/01/31 15:17:48 bradleyb
26 * Makefile and conf.h fixes
28 * Revision 1.1.1.1 2001/01/19 03:29:58 bradleyb
31 * Revision 1.1.1.1 1999/06/14 21:57:47 donut
32 * Import of d1x 1.37 source.
34 * Revision 1.4 1995/10/10 22:20:09 allender
35 * new morphing code from Matt
37 * Revision 1.3 1995/08/31 15:40:24 allender
38 * swap color data correctly
40 * Revision 1.2 1995/05/11 13:06:38 allender
41 * fix int --> short problem
43 * Revision 1.1 1995/05/05 08:51:41 allender
46 * Revision 1.1 1995/04/17 06:44:33 matt
57 static char rcsid[] = "$Id: interp.c,v 1.4 2001-10-31 03:54:50 bradleyb Exp $";
67 #define OP_EOF 0 //eof
68 #define OP_DEFPOINTS 1 //defpoints
69 #define OP_FLATPOLY 2 //flat-shaded polygon
70 #define OP_TMAPPOLY 3 //texture-mapped polygon
71 #define OP_SORTNORM 4 //sort by normal
72 #define OP_RODBM 5 //rod bitmap
73 #define OP_SUBCALL 6 //call a subobject
74 #define OP_DEFP_START 7 //defpoints with start
75 #define OP_GLOW 8 //glow value for next poly
77 #define N_OPCODES (sizeof(opcode_table) / sizeof(*opcode_table))
79 #define MAX_POINTS_PER_POLY 25
81 short highest_texture_num;
82 int g3d_interp_outline;
84 g3s_point *Interp_point_list=NULL;
86 #define MAX_INTERP_COLORS 100
88 //this is a table of mappings from RGB15 to palette colors
89 struct {short pal_entry,rgb15;} interp_color_table[MAX_INTERP_COLORS];
91 int n_interp_colors=0;
93 //gives the interpreter an array of points to use
94 void g3_set_interp_points(g3s_point *pointlist)
96 Interp_point_list = pointlist;
99 #define w(p) (*((short *) (p)))
100 #define wp(p) ((short *) (p))
101 #define vp(p) ((vms_vector *) (p))
103 void rotate_point_list(g3s_point *dest,vms_vector *src,int n)
106 g3_rotate_point(dest++,src++);
109 vms_angvec zero_angles = {0,0,0};
111 g3s_point *point_list[MAX_POINTS_PER_POLY];
115 //calls the object interpreter to render an object. The object renderer
116 //is really a seperate pipeline. returns true if drew
117 bool g3_draw_polygon_model(void *model_ptr,grs_bitmap **model_bitmaps,vms_angvec *anim_angles,fix model_light,fix *glow_values)
119 ubyte *p = model_ptr;
121 glow_num = -1; //glow off by default
123 while (w(p) != OP_EOF)
130 rotate_point_list(Interp_point_list,vp(p+4),n);
131 p += n*sizeof(struct vms_vector) + 4;
136 case OP_DEFP_START: {
140 rotate_point_list(&Interp_point_list[s],vp(p+8),n);
141 p += n*sizeof(struct vms_vector) + 8;
149 Assert( nv < MAX_POINTS_PER_POLY );
150 if (g3_check_normal_facing(vp(p+4),vp(p+16)) > 0) {
156 // DPH: Now we treat this color as 15bpp
157 // gr_setcolor(w(p+28));
159 //l = (32 * model_light) >> 16;
160 l = f2i(fixmul(i2f(32), model_light));
162 else if (l>32) l = 32;
163 cc = gr_find_closest_color_15bpp(w(p+28));
164 c = gr_fade_table[(l<<8)|cc];
168 point_list[i] = Interp_point_list + wp(p+30)[i];
170 g3_draw_poly(nv,point_list);
173 p += 30 + ((nv&~1)+1)*2;
182 Assert( nv < MAX_POINTS_PER_POLY );
183 if (g3_check_normal_facing(vp(p+4),vp(p+16)) > 0) {
187 //calculate light from surface normal
189 if (glow_num < 0) { //no glow
191 light = -vm_vec_dot(&View_matrix.fvec,vp(p+16));
192 light = f1_0/4 + (light*3)/4;
193 light = fixmul(light,model_light);
196 light = glow_values[glow_num];
200 //now poke light into l values
202 uvl_list = (g3s_uvl *) (p+30+((nv&~1)+1)*2);
205 uvl_list[i].l = light;
208 point_list[i] = Interp_point_list + wp(p+30)[i];
210 g3_draw_tmap(nv,point_list,uvl_list,model_bitmaps[w(p+28)]);
213 p += 30 + ((nv&~1)+1)*2 + nv*12;
220 if (g3_check_normal_facing(vp(p+16),vp(p+4)) > 0) { //facing
222 //draw back then front
224 g3_draw_polygon_model(p+w(p+30),model_bitmaps,anim_angles,model_light,glow_values);
225 g3_draw_polygon_model(p+w(p+28),model_bitmaps,anim_angles,model_light,glow_values);
228 else { //not facing. draw front then back
230 g3_draw_polygon_model(p+w(p+28),model_bitmaps,anim_angles,model_light,glow_values);
231 g3_draw_polygon_model(p+w(p+30),model_bitmaps,anim_angles,model_light,glow_values);
240 g3s_point rod_bot_p,rod_top_p;
242 g3_rotate_point(&rod_bot_p,vp(p+20));
243 g3_rotate_point(&rod_top_p,vp(p+4));
245 g3_draw_rod_tmap(model_bitmaps[w(p+2)],&rod_bot_p,w(p+16),&rod_top_p,w(p+32),f1_0);
255 a = &anim_angles[w(p+2)];
259 g3_start_instance_angles(vp(p+4),a);
261 g3_draw_polygon_model(p+w(p+16),model_bitmaps,anim_angles,model_light,glow_values);
284 extern int gr_find_closest_color_15bpp( int rgb );
290 //alternate interpreter for morphing object
291 bool g3_draw_morphing_model(void *model_ptr,grs_bitmap **model_bitmaps,vms_angvec *anim_angles,fix model_light,vms_vector *new_points)
293 ubyte *p = model_ptr;
294 fix *glow_values = NULL;
296 glow_num = -1; //glow off by default
298 while (w(p) != OP_EOF)
305 rotate_point_list(Interp_point_list,new_points,n);
306 p += n*sizeof(struct vms_vector) + 4;
311 case OP_DEFP_START: {
315 rotate_point_list(&Interp_point_list[s],new_points,n);
316 p += n*sizeof(struct vms_vector) + 8;
325 gr_setcolor(w(p+28));
328 point_list[i] = Interp_point_list + wp(p+30)[i];
330 for (ntris=nv-2;ntris;ntris--) {
332 point_list[2] = Interp_point_list + wp(p+30)[i++];
334 g3_check_and_draw_poly(3,point_list,NULL,NULL);
336 point_list[1] = point_list[2];
340 p += 30 + ((nv&~1)+1)*2;
348 g3s_uvl morph_uvls[3];
352 //calculate light from surface normal
354 if (glow_num < 0) { //no glow
356 light = -vm_vec_dot(&View_matrix.fvec,vp(p+16));
357 light = f1_0/4 + (light*3)/4;
358 light = fixmul(light,model_light);
361 light = glow_values[glow_num];
365 //now poke light into l values
367 uvl_list = (g3s_uvl *) (p+30+((nv&~1)+1)*2);
370 morph_uvls[i].l = light;
373 point_list[i] = Interp_point_list + wp(p+30)[i];
375 morph_uvls[i].u = uvl_list[i].u;
376 morph_uvls[i].v = uvl_list[i].v;
379 for (ntris=nv-2;ntris;ntris--) {
381 point_list[2] = Interp_point_list + wp(p+30)[i];
382 morph_uvls[2].u = uvl_list[i].u;
383 morph_uvls[2].v = uvl_list[i].v;
386 g3_check_and_draw_tmap(3,point_list,uvl_list,model_bitmaps[w(p+28)],NULL,NULL);
388 point_list[1] = point_list[2];
389 morph_uvls[1].u = morph_uvls[2].u;
390 morph_uvls[1].v = morph_uvls[2].v;
394 p += 30 + ((nv&~1)+1)*2 + nv*12;
401 if (g3_check_normal_facing(vp(p+16),vp(p+4)) > 0) { //facing
403 //draw back then front
405 g3_draw_morphing_model(p+w(p+30),model_bitmaps,anim_angles,model_light,new_points);
406 g3_draw_morphing_model(p+w(p+28),model_bitmaps,anim_angles,model_light,new_points);
409 else { //not facing. draw front then back
411 g3_draw_morphing_model(p+w(p+28),model_bitmaps,anim_angles,model_light,new_points);
412 g3_draw_morphing_model(p+w(p+30),model_bitmaps,anim_angles,model_light,new_points);
421 g3s_point rod_bot_p,rod_top_p;
423 g3_rotate_point(&rod_bot_p,vp(p+20));
424 g3_rotate_point(&rod_top_p,vp(p+4));
426 g3_draw_rod_tmap(model_bitmaps[w(p+2)],&rod_bot_p,w(p+16),&rod_top_p,w(p+32),f1_0);
436 a = &anim_angles[w(p+2)];
440 g3_start_instance_angles(vp(p+4),a);
442 g3_draw_polygon_model(p+w(p+16),model_bitmaps,anim_angles,model_light,glow_values);
463 void init_model_sub(ubyte *p)
465 Assert(++nest_count < 1000);
467 while (w(p) != OP_EOF) {
473 p += n*sizeof(struct vms_vector) + 4;
477 case OP_DEFP_START: {
479 p += n*sizeof(struct vms_vector) + 8;
486 Assert(nv > 2); //must have 3 or more points
488 // *wp(p+28) = (short)gr_find_closest_color_15bpp(w(p+28));
490 p += 30 + ((nv&~1)+1)*2;
498 Assert(nv > 2); //must have 3 or more points
500 if (w(p+28) > highest_texture_num)
501 highest_texture_num = w(p+28);
503 p += 30 + ((nv&~1)+1)*2 + nv*12;
510 init_model_sub(p+w(p+28));
511 init_model_sub(p+w(p+30));
523 init_model_sub(p+w(p+16));
538 //init code for bitmap models
539 void g3_init_polygon_model(void *model_ptr)
545 highest_texture_num = -1;
547 init_model_sub((ubyte *) model_ptr);