1 /* $Id: interp.c,v 1.12 2003-02-13 22:02:29 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.
17 * 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.12 2003-02-13 22:02:29 btb Exp $";
55 #define OP_EOF 0 //eof
56 #define OP_DEFPOINTS 1 //defpoints
57 #define OP_FLATPOLY 2 //flat-shaded polygon
58 #define OP_TMAPPOLY 3 //texture-mapped polygon
59 #define OP_SORTNORM 4 //sort by normal
60 #define OP_RODBM 5 //rod bitmap
61 #define OP_SUBCALL 6 //call a subobject
62 #define OP_DEFP_START 7 //defpoints with start
63 #define OP_GLOW 8 //glow value for next poly
65 //#define N_OPCODES (sizeof(opcode_table) / sizeof(*opcode_table))
67 #define MAX_POINTS_PER_POLY 25
69 short highest_texture_num;
70 int g3d_interp_outline;
72 g3s_point *Interp_point_list = NULL;
74 #define MAX_INTERP_COLORS 100
76 //this is a table of mappings from RGB15 to palette colors
77 struct {short pal_entry,rgb15;} interp_color_table[MAX_INTERP_COLORS];
79 int n_interp_colors=0;
81 //gives the interpreter an array of points to use
82 void g3_set_interp_points(g3s_point *pointlist)
84 Interp_point_list = pointlist;
87 #define w(p) (*((short *) (p)))
88 #define wp(p) ((short *) (p))
89 #define fp(p) ((fix *) (p))
90 #define vp(p) ((vms_vector *) (p))
92 void rotate_point_list(g3s_point *dest,vms_vector *src,int n)
95 g3_rotate_point(dest++,src++);
98 vms_angvec zero_angles = {0,0,0};
100 g3s_point *point_list[MAX_POINTS_PER_POLY];
104 #ifdef WORDS_BIGENDIAN
105 void short_swap(short *s)
110 void fix_swap(fix *f)
112 *f = (fix)SWAPINT((int)*f);
115 void vms_vector_swap(vms_vector *v)
122 void swap_polygon_model_data(ubyte *data)
131 while (w(p) != OP_EOF) {
134 short_swap(wp(p + 2));
136 for (i = 0; i < n; i++)
137 vms_vector_swap(vp((p + 4) + (i * sizeof(vms_vector))));
138 p += n*sizeof(struct vms_vector) + 4;
142 short_swap(wp(p + 2));
143 short_swap(wp(p + 4));
145 for (i = 0; i < n; i++)
146 vms_vector_swap(vp((p + 8) + (i * sizeof(vms_vector))));
147 p += n*sizeof(struct vms_vector) + 8;
153 vms_vector_swap(vp(p + 4));
154 vms_vector_swap(vp(p + 16));
155 short_swap(wp(p+28));
157 // swap the colors 0 and 255 here!!!!
160 else if (w(p+28) == 255)
163 for (i=0; i < n; i++)
164 short_swap(wp(p + 30 + (i * 2)));
165 p += 30 + ((n&~1)+1)*2;
171 vms_vector_swap(vp(p + 4));
172 vms_vector_swap(vp(p + 16));
174 uvl_val = (g3s_uvl *)((p+30+((n&~1)+1)*2) + (i * sizeof(g3s_uvl)));
175 fix_swap(&uvl_val->u);
176 fix_swap(&uvl_val->v);
178 short_swap(wp(p+28));
180 short_swap(wp(p + 30 + (i * 2)));
181 p += 30 + ((n&~1)+1)*2 + n*12;
185 vms_vector_swap(vp(p + 4));
186 vms_vector_swap(vp(p + 16));
187 short_swap(wp(p + 28));
188 short_swap(wp(p + 30));
189 swap_polygon_model_data(p + w(p+28));
190 swap_polygon_model_data(p + w(p+30));
195 vms_vector_swap(vp(p + 20));
196 vms_vector_swap(vp(p + 4));
198 fix_swap(fp(p + 16));
199 fix_swap(fp(p + 32));
205 vms_vector_swap(vp(p+4));
206 short_swap(wp(p+16));
207 swap_polygon_model_data(p + w(p+16));
212 short_swap(wp(p + 2));
217 Error("invalid polygon model\n"); //Int3();
224 #ifdef WORDS_NEED_ALIGNMENT
225 void add_chunk(ubyte *old_base, ubyte *new_base, int offset,
226 chunk *chunk_list, int *no_chunks)
228 Assert(*no_chunks + 1 < MAX_CHUNKS); //increase MAX_CHUNKS if you get this
229 chunk_list[*no_chunks].old_base = old_base;
230 chunk_list[*no_chunks].new_base = new_base;
231 chunk_list[*no_chunks].offset = offset;
232 chunk_list[*no_chunks].correction = 0;
237 * finds what chunks the data points to, adds them to the chunk_list,
238 * and returns the length of the current chunk
240 int get_chunks(ubyte *data, ubyte *new_data, chunk *list, int *no)
245 while (INTEL_SHORT(w(p)) != OP_EOF) {
246 switch (INTEL_SHORT(w(p))) {
248 n = INTEL_SHORT(w(p+2));
249 p += n*sizeof(struct vms_vector) + 4;
252 n = INTEL_SHORT(w(p+2));
253 p += n*sizeof(struct vms_vector) + 8;
256 n = INTEL_SHORT(w(p+2));
257 p += 30 + ((n&~1)+1)*2;
260 n = INTEL_SHORT(w(p+2));
261 p += 30 + ((n&~1)+1)*2 + n*12;
264 add_chunk(p, p - data + new_data, 28, list, no);
265 add_chunk(p, p - data + new_data, 30, list, no);
272 add_chunk(p, p - data + new_data, 16, list, no);
279 Error("invalid polygon model\n");
284 #endif //def WORDS_NEED_ALIGNMENT
286 void verify(ubyte *data)
291 while (w(p) != OP_EOF) {
295 p += n*sizeof(struct vms_vector) + 4;
299 p += n*sizeof(struct vms_vector) + 8;
303 p += 30 + ((n&~1)+1)*2;
307 p += 30 + ((n&~1)+1)*2 + n*12;
310 verify(p + w(p + 28));
311 verify(p + w(p + 30));
318 verify(p + w(p + 16));
325 Error("invalid polygon model\n");
331 //calls the object interpreter to render an object. The object renderer
332 //is really a seperate pipeline. returns true if drew
333 bool g3_draw_polygon_model(void *model_ptr,grs_bitmap **model_bitmaps,vms_angvec *anim_angles,fix model_light,fix *glow_values)
335 ubyte *p = model_ptr;
337 glow_num = -1; //glow off by default
339 while (w(p) != OP_EOF)
346 rotate_point_list(Interp_point_list,vp(p+4),n);
347 p += n*sizeof(struct vms_vector) + 4;
352 case OP_DEFP_START: {
356 rotate_point_list(&Interp_point_list[s],vp(p+8),n);
357 p += n*sizeof(struct vms_vector) + 8;
365 Assert( nv < MAX_POINTS_PER_POLY );
366 if (g3_check_normal_facing(vp(p+4),vp(p+16)) > 0) {
372 // DPH: Now we treat this color as 15bpp
373 // gr_setcolor(w(p+28));
375 //l = (32 * model_light) >> 16;
376 l = f2i(fixmul(i2f(32), model_light));
378 else if (l>32) l = 32;
379 cc = gr_find_closest_color_15bpp(w(p+28));
380 c = gr_fade_table[(l<<8)|cc];
384 point_list[i] = Interp_point_list + wp(p+30)[i];
386 g3_draw_poly(nv,point_list);
389 p += 30 + ((nv&~1)+1)*2;
398 Assert( nv < MAX_POINTS_PER_POLY );
399 if (g3_check_normal_facing(vp(p+4),vp(p+16)) > 0) {
403 //calculate light from surface normal
405 if (glow_num < 0) { //no glow
407 light = -vm_vec_dot(&View_matrix.fvec,vp(p+16));
408 light = f1_0/4 + (light*3)/4;
409 light = fixmul(light,model_light);
412 light = glow_values[glow_num];
416 //now poke light into l values
418 uvl_list = (g3s_uvl *) (p+30+((nv&~1)+1)*2);
421 uvl_list[i].l = light;
424 point_list[i] = Interp_point_list + wp(p+30)[i];
426 g3_draw_tmap(nv,point_list,uvl_list,model_bitmaps[w(p+28)]);
429 p += 30 + ((nv&~1)+1)*2 + nv*12;
436 if (g3_check_normal_facing(vp(p+16),vp(p+4)) > 0) { //facing
438 //draw back then front
440 g3_draw_polygon_model(p+w(p+30),model_bitmaps,anim_angles,model_light,glow_values);
441 g3_draw_polygon_model(p+w(p+28),model_bitmaps,anim_angles,model_light,glow_values);
444 else { //not facing. draw front then back
446 g3_draw_polygon_model(p+w(p+28),model_bitmaps,anim_angles,model_light,glow_values);
447 g3_draw_polygon_model(p+w(p+30),model_bitmaps,anim_angles,model_light,glow_values);
456 g3s_point rod_bot_p,rod_top_p;
458 g3_rotate_point(&rod_bot_p,vp(p+20));
459 g3_rotate_point(&rod_top_p,vp(p+4));
461 g3_draw_rod_tmap(model_bitmaps[w(p+2)],&rod_bot_p,w(p+16),&rod_top_p,w(p+32),f1_0);
471 a = &anim_angles[w(p+2)];
475 g3_start_instance_angles(vp(p+4),a);
477 g3_draw_polygon_model(p+w(p+16),model_bitmaps,anim_angles,model_light,glow_values);
495 Error("invalid polygon model\n");
500 extern int gr_find_closest_color_15bpp( int rgb );
506 //alternate interpreter for morphing object
507 bool g3_draw_morphing_model(void *model_ptr,grs_bitmap **model_bitmaps,vms_angvec *anim_angles,fix model_light,vms_vector *new_points)
509 ubyte *p = model_ptr;
510 fix *glow_values = NULL;
512 glow_num = -1; //glow off by default
514 while (w(p) != OP_EOF)
521 rotate_point_list(Interp_point_list,new_points,n);
522 p += n*sizeof(struct vms_vector) + 4;
527 case OP_DEFP_START: {
531 rotate_point_list(&Interp_point_list[s],new_points,n);
532 p += n*sizeof(struct vms_vector) + 8;
541 gr_setcolor(w(p+28));
544 point_list[i] = Interp_point_list + wp(p+30)[i];
546 for (ntris=nv-2;ntris;ntris--) {
548 point_list[2] = Interp_point_list + wp(p+30)[i++];
550 g3_check_and_draw_poly(3,point_list,NULL,NULL);
552 point_list[1] = point_list[2];
556 p += 30 + ((nv&~1)+1)*2;
564 g3s_uvl morph_uvls[3];
568 //calculate light from surface normal
570 if (glow_num < 0) { //no glow
572 light = -vm_vec_dot(&View_matrix.fvec,vp(p+16));
573 light = f1_0/4 + (light*3)/4;
574 light = fixmul(light,model_light);
577 light = glow_values[glow_num];
581 //now poke light into l values
583 uvl_list = (g3s_uvl *) (p+30+((nv&~1)+1)*2);
586 morph_uvls[i].l = light;
589 point_list[i] = Interp_point_list + wp(p+30)[i];
591 morph_uvls[i].u = uvl_list[i].u;
592 morph_uvls[i].v = uvl_list[i].v;
595 for (ntris=nv-2;ntris;ntris--) {
597 point_list[2] = Interp_point_list + wp(p+30)[i];
598 morph_uvls[2].u = uvl_list[i].u;
599 morph_uvls[2].v = uvl_list[i].v;
602 g3_check_and_draw_tmap(3,point_list,uvl_list,model_bitmaps[w(p+28)],NULL,NULL);
604 point_list[1] = point_list[2];
605 morph_uvls[1].u = morph_uvls[2].u;
606 morph_uvls[1].v = morph_uvls[2].v;
610 p += 30 + ((nv&~1)+1)*2 + nv*12;
617 if (g3_check_normal_facing(vp(p+16),vp(p+4)) > 0) { //facing
619 //draw back then front
621 g3_draw_morphing_model(p+w(p+30),model_bitmaps,anim_angles,model_light,new_points);
622 g3_draw_morphing_model(p+w(p+28),model_bitmaps,anim_angles,model_light,new_points);
625 else { //not facing. draw front then back
627 g3_draw_morphing_model(p+w(p+28),model_bitmaps,anim_angles,model_light,new_points);
628 g3_draw_morphing_model(p+w(p+30),model_bitmaps,anim_angles,model_light,new_points);
637 g3s_point rod_bot_p,rod_top_p;
639 g3_rotate_point(&rod_bot_p,vp(p+20));
640 g3_rotate_point(&rod_top_p,vp(p+4));
642 g3_draw_rod_tmap(model_bitmaps[w(p+2)],&rod_bot_p,w(p+16),&rod_top_p,w(p+32),f1_0);
652 a = &anim_angles[w(p+2)];
656 g3_start_instance_angles(vp(p+4),a);
658 g3_draw_polygon_model(p+w(p+16),model_bitmaps,anim_angles,model_light,glow_values);
679 void init_model_sub(ubyte *p)
681 Assert(++nest_count < 1000);
683 while (w(p) != OP_EOF) {
689 p += n*sizeof(struct vms_vector) + 4;
693 case OP_DEFP_START: {
695 p += n*sizeof(struct vms_vector) + 8;
702 Assert(nv > 2); //must have 3 or more points
704 // *wp(p+28) = (short)gr_find_closest_color_15bpp(w(p+28));
706 p += 30 + ((nv&~1)+1)*2;
714 Assert(nv > 2); //must have 3 or more points
716 if (w(p+28) > highest_texture_num)
717 highest_texture_num = w(p+28);
719 p += 30 + ((nv&~1)+1)*2 + nv*12;
726 init_model_sub(p+w(p+28));
727 init_model_sub(p+w(p+30));
739 init_model_sub(p+w(p+16));
749 Error("invalid polygon model\n");
754 //init code for bitmap models
755 void g3_init_polygon_model(void *model_ptr)
761 highest_texture_num = -1;
763 init_model_sub((ubyte *) model_ptr);