1 /* $Id: interp.c,v 1.7 2002-08-09 00:48:57 btb Exp $ */
3 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
4 SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
5 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
6 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
7 IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
8 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
9 FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
10 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
11 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
12 COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
16 * Polygon object interpreter
20 * Revision 1.4 1995/10/10 22:20:09 allender
21 * new morphing code from Matt
23 * Revision 1.3 1995/08/31 15:40:24 allender
24 * swap color data correctly
26 * Revision 1.2 1995/05/11 13:06:38 allender
27 * fix int --> short problem
29 * Revision 1.1 1995/05/05 08:51:41 allender
32 * Revision 1.1 1995/04/17 06:44:33 matt
43 static char rcsid[] = "$Id: interp.c,v 1.7 2002-08-09 00:48:57 btb Exp $";
54 #define OP_EOF 0 //eof
55 #define OP_DEFPOINTS 1 //defpoints
56 #define OP_FLATPOLY 2 //flat-shaded polygon
57 #define OP_TMAPPOLY 3 //texture-mapped polygon
58 #define OP_SORTNORM 4 //sort by normal
59 #define OP_RODBM 5 //rod bitmap
60 #define OP_SUBCALL 6 //call a subobject
61 #define OP_DEFP_START 7 //defpoints with start
62 #define OP_GLOW 8 //glow value for next poly
64 #define N_OPCODES (sizeof(opcode_table) / sizeof(*opcode_table))
66 #define MAX_POINTS_PER_POLY 25
68 short highest_texture_num;
69 int g3d_interp_outline;
71 g3s_point *Interp_point_list = NULL;
73 #define MAX_INTERP_COLORS 100
75 //this is a table of mappings from RGB15 to palette colors
76 struct {short pal_entry,rgb15;} interp_color_table[MAX_INTERP_COLORS];
78 int n_interp_colors=0;
80 //gives the interpreter an array of points to use
81 void g3_set_interp_points(g3s_point *pointlist)
83 Interp_point_list = pointlist;
86 #define w(p) (*((short *) (p)))
87 #define wp(p) ((short *) (p))
88 #define vp(p) ((vms_vector *) (p))
90 void rotate_point_list(g3s_point *dest,vms_vector *src,int n)
93 g3_rotate_point(dest++,src++);
96 vms_angvec zero_angles = {0,0,0};
98 g3s_point *point_list[MAX_POINTS_PER_POLY];
102 #ifdef WORDS_BIGENDIAN
103 void short_swap(short *s)
108 void vms_vector_swap(vms_vector *v)
110 v->x = (fix)swapint((int)v->x);
111 v->y = (fix)swapint((int)v->y);
112 v->z = (fix)swapint((int)v->z);
115 void swap_polygon_model_data(ubyte *data)
124 while (w(p) != OP_EOF) {
127 short_swap(wp(p + 2));
129 for (i = 0; i < n; i++)
130 vms_vector_swap(vp((p + 4) + (i * sizeof(vms_vector))));
131 p += n*sizeof(struct vms_vector) + 4;
135 short_swap(wp(p + 2));
136 short_swap(wp(p + 4));
138 for (i = 0; i < n; i++)
139 vms_vector_swap(vp((p + 8) + (i * sizeof(vms_vector))));
140 p += n*sizeof(struct vms_vector) + 8;
146 vms_vector_swap(vp(p + 4));
147 vms_vector_swap(vp(p + 16));
148 short_swap(wp(p+28));
150 // swap the colors 0 and 255 here!!!!
153 else if (w(p+28) == 255)
156 for (i=0; i < n; i++)
157 short_swap(wp(p + 30 + (i * 2)));
158 p += 30 + ((n&~1)+1)*2;
164 vms_vector_swap(vp(p + 4));
165 vms_vector_swap(vp(p + 16));
167 uvl_val = (g3s_uvl *)((p+30+((n&~1)+1)*2) + (i * sizeof(g3s_uvl)));
168 uvl_val->u = (fix)swapint((int)uvl_val->u);
169 uvl_val->v = (fix)swapint((int)uvl_val->v);
171 short_swap(wp(p+28));
173 short_swap(wp(p + 30 + (i * 2)));
174 p += 30 + ((n&~1)+1)*2 + n*12;
178 vms_vector_swap(vp(p + 4));
179 vms_vector_swap(vp(p + 16));
180 short_swap(wp(p + 28));
181 short_swap(wp(p + 30));
182 swap_polygon_model_data(p + w(p+28));
183 swap_polygon_model_data(p + w(p+30));
188 vms_vector_swap(vp(p + 20));
189 vms_vector_swap(vp(p + 4));
191 *((int *)(p + 16)) = swapint(*((int *)(p + 16)));
192 *((int *)(p + 32)) = swapint(*((int *)(p + 32)));
198 vms_vector_swap(vp(p+4));
199 short_swap(wp(p+16));
200 swap_polygon_model_data(p + w(p+16));
205 short_swap(wp(p + 2));
217 //calls the object interpreter to render an object. The object renderer
218 //is really a seperate pipeline. returns true if drew
219 bool g3_draw_polygon_model(void *model_ptr,grs_bitmap **model_bitmaps,vms_angvec *anim_angles,fix model_light,fix *glow_values)
221 ubyte *p = model_ptr;
223 glow_num = -1; //glow off by default
225 while (w(p) != OP_EOF)
232 rotate_point_list(Interp_point_list,vp(p+4),n);
233 p += n*sizeof(struct vms_vector) + 4;
238 case OP_DEFP_START: {
242 rotate_point_list(&Interp_point_list[s],vp(p+8),n);
243 p += n*sizeof(struct vms_vector) + 8;
251 Assert( nv < MAX_POINTS_PER_POLY );
252 if (g3_check_normal_facing(vp(p+4),vp(p+16)) > 0) {
258 // DPH: Now we treat this color as 15bpp
259 // gr_setcolor(w(p+28));
261 //l = (32 * model_light) >> 16;
262 l = f2i(fixmul(i2f(32), model_light));
264 else if (l>32) l = 32;
265 cc = gr_find_closest_color_15bpp(w(p+28));
266 c = gr_fade_table[(l<<8)|cc];
270 point_list[i] = Interp_point_list + wp(p+30)[i];
272 g3_draw_poly(nv,point_list);
275 p += 30 + ((nv&~1)+1)*2;
284 Assert( nv < MAX_POINTS_PER_POLY );
285 if (g3_check_normal_facing(vp(p+4),vp(p+16)) > 0) {
289 //calculate light from surface normal
291 if (glow_num < 0) { //no glow
293 light = -vm_vec_dot(&View_matrix.fvec,vp(p+16));
294 light = f1_0/4 + (light*3)/4;
295 light = fixmul(light,model_light);
298 light = glow_values[glow_num];
302 //now poke light into l values
304 uvl_list = (g3s_uvl *) (p+30+((nv&~1)+1)*2);
307 uvl_list[i].l = light;
310 point_list[i] = Interp_point_list + wp(p+30)[i];
312 g3_draw_tmap(nv,point_list,uvl_list,model_bitmaps[w(p+28)]);
315 p += 30 + ((nv&~1)+1)*2 + nv*12;
322 if (g3_check_normal_facing(vp(p+16),vp(p+4)) > 0) { //facing
324 //draw back then front
326 g3_draw_polygon_model(p+w(p+30),model_bitmaps,anim_angles,model_light,glow_values);
327 g3_draw_polygon_model(p+w(p+28),model_bitmaps,anim_angles,model_light,glow_values);
330 else { //not facing. draw front then back
332 g3_draw_polygon_model(p+w(p+28),model_bitmaps,anim_angles,model_light,glow_values);
333 g3_draw_polygon_model(p+w(p+30),model_bitmaps,anim_angles,model_light,glow_values);
342 g3s_point rod_bot_p,rod_top_p;
344 g3_rotate_point(&rod_bot_p,vp(p+20));
345 g3_rotate_point(&rod_top_p,vp(p+4));
347 g3_draw_rod_tmap(model_bitmaps[w(p+2)],&rod_bot_p,w(p+16),&rod_top_p,w(p+32),f1_0);
357 a = &anim_angles[w(p+2)];
361 g3_start_instance_angles(vp(p+4),a);
363 g3_draw_polygon_model(p+w(p+16),model_bitmaps,anim_angles,model_light,glow_values);
386 extern int gr_find_closest_color_15bpp( int rgb );
392 //alternate interpreter for morphing object
393 bool g3_draw_morphing_model(void *model_ptr,grs_bitmap **model_bitmaps,vms_angvec *anim_angles,fix model_light,vms_vector *new_points)
395 ubyte *p = model_ptr;
396 fix *glow_values = NULL;
398 glow_num = -1; //glow off by default
400 while (w(p) != OP_EOF)
407 rotate_point_list(Interp_point_list,new_points,n);
408 p += n*sizeof(struct vms_vector) + 4;
413 case OP_DEFP_START: {
417 rotate_point_list(&Interp_point_list[s],new_points,n);
418 p += n*sizeof(struct vms_vector) + 8;
427 gr_setcolor(w(p+28));
430 point_list[i] = Interp_point_list + wp(p+30)[i];
432 for (ntris=nv-2;ntris;ntris--) {
434 point_list[2] = Interp_point_list + wp(p+30)[i++];
436 g3_check_and_draw_poly(3,point_list,NULL,NULL);
438 point_list[1] = point_list[2];
442 p += 30 + ((nv&~1)+1)*2;
450 g3s_uvl morph_uvls[3];
454 //calculate light from surface normal
456 if (glow_num < 0) { //no glow
458 light = -vm_vec_dot(&View_matrix.fvec,vp(p+16));
459 light = f1_0/4 + (light*3)/4;
460 light = fixmul(light,model_light);
463 light = glow_values[glow_num];
467 //now poke light into l values
469 uvl_list = (g3s_uvl *) (p+30+((nv&~1)+1)*2);
472 morph_uvls[i].l = light;
475 point_list[i] = Interp_point_list + wp(p+30)[i];
477 morph_uvls[i].u = uvl_list[i].u;
478 morph_uvls[i].v = uvl_list[i].v;
481 for (ntris=nv-2;ntris;ntris--) {
483 point_list[2] = Interp_point_list + wp(p+30)[i];
484 morph_uvls[2].u = uvl_list[i].u;
485 morph_uvls[2].v = uvl_list[i].v;
488 g3_check_and_draw_tmap(3,point_list,uvl_list,model_bitmaps[w(p+28)],NULL,NULL);
490 point_list[1] = point_list[2];
491 morph_uvls[1].u = morph_uvls[2].u;
492 morph_uvls[1].v = morph_uvls[2].v;
496 p += 30 + ((nv&~1)+1)*2 + nv*12;
503 if (g3_check_normal_facing(vp(p+16),vp(p+4)) > 0) { //facing
505 //draw back then front
507 g3_draw_morphing_model(p+w(p+30),model_bitmaps,anim_angles,model_light,new_points);
508 g3_draw_morphing_model(p+w(p+28),model_bitmaps,anim_angles,model_light,new_points);
511 else { //not facing. draw front then back
513 g3_draw_morphing_model(p+w(p+28),model_bitmaps,anim_angles,model_light,new_points);
514 g3_draw_morphing_model(p+w(p+30),model_bitmaps,anim_angles,model_light,new_points);
523 g3s_point rod_bot_p,rod_top_p;
525 g3_rotate_point(&rod_bot_p,vp(p+20));
526 g3_rotate_point(&rod_top_p,vp(p+4));
528 g3_draw_rod_tmap(model_bitmaps[w(p+2)],&rod_bot_p,w(p+16),&rod_top_p,w(p+32),f1_0);
538 a = &anim_angles[w(p+2)];
542 g3_start_instance_angles(vp(p+4),a);
544 g3_draw_polygon_model(p+w(p+16),model_bitmaps,anim_angles,model_light,glow_values);
565 void init_model_sub(ubyte *p)
567 Assert(++nest_count < 1000);
569 while (w(p) != OP_EOF) {
575 p += n*sizeof(struct vms_vector) + 4;
579 case OP_DEFP_START: {
581 p += n*sizeof(struct vms_vector) + 8;
588 Assert(nv > 2); //must have 3 or more points
590 // *wp(p+28) = (short)gr_find_closest_color_15bpp(w(p+28));
592 p += 30 + ((nv&~1)+1)*2;
600 Assert(nv > 2); //must have 3 or more points
602 if (w(p+28) > highest_texture_num)
603 highest_texture_num = w(p+28);
605 p += 30 + ((nv&~1)+1)*2 + nv*12;
612 init_model_sub(p+w(p+28));
613 init_model_sub(p+w(p+30));
625 init_model_sub(p+w(p+16));
640 //init code for bitmap models
641 void g3_init_polygon_model(void *model_ptr)
647 highest_texture_num = -1;
649 init_model_sub((ubyte *) model_ptr);