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.
16 * Polygon object interpreter
33 #define OP_EOF 0 //eof
34 #define OP_DEFPOINTS 1 //defpoints
35 #define OP_FLATPOLY 2 //flat-shaded polygon
36 #define OP_TMAPPOLY 3 //texture-mapped polygon
37 #define OP_SORTNORM 4 //sort by normal
38 #define OP_RODBM 5 //rod bitmap
39 #define OP_SUBCALL 6 //call a subobject
40 #define OP_DEFP_START 7 //defpoints with start
41 #define OP_GLOW 8 //glow value for next poly
43 //#define N_OPCODES (sizeof(opcode_table) / sizeof(*opcode_table))
45 #define MAX_POINTS_PER_POLY 25
47 short highest_texture_num;
48 int g3d_interp_outline;
50 g3s_point *Interp_point_list = NULL;
52 #define MAX_INTERP_COLORS 100
54 //this is a table of mappings from RGB15 to palette colors
55 struct {short pal_entry,rgb15;} interp_color_table[MAX_INTERP_COLORS];
57 int n_interp_colors=0;
59 //gives the interpreter an array of points to use
60 void g3_set_interp_points(g3s_point *pointlist)
62 Interp_point_list = pointlist;
65 #define w(p) (*((short *) (p)))
66 #define wp(p) ((short *) (p))
67 #define fp(p) ((fix *) (p))
68 #define vp(p) ((vms_vector *) (p))
70 void rotate_point_list(g3s_point *dest,vms_vector *src,int n)
73 g3_rotate_point(dest++,src++);
76 vms_angvec zero_angles = {0,0,0};
78 g3s_point *point_list[MAX_POINTS_PER_POLY];
82 #ifdef WORDS_BIGENDIAN
83 void short_swap(short *s)
90 *f = (fix)SWAPINT((int)*f);
93 void vms_vector_swap(vms_vector *v)
100 void fixang_swap(fixang *f)
102 *f = (fixang)SWAPSHORT((short)*f);
105 void vms_angvec_swap(vms_angvec *v)
112 void swap_polygon_model_data(ubyte *data)
121 while (w(p) != OP_EOF) {
124 short_swap(wp(p + 2));
126 for (i = 0; i < n; i++)
127 vms_vector_swap(vp((p + 4) + (i * sizeof(vms_vector))));
128 p += n*sizeof(struct vms_vector) + 4;
132 short_swap(wp(p + 2));
133 short_swap(wp(p + 4));
135 for (i = 0; i < n; i++)
136 vms_vector_swap(vp((p + 8) + (i * sizeof(vms_vector))));
137 p += n*sizeof(struct vms_vector) + 8;
143 vms_vector_swap(vp(p + 4));
144 vms_vector_swap(vp(p + 16));
145 short_swap(wp(p+28));
147 // swap the colors 0 and 255 here!!!!
150 else if (w(p+28) == 255)
153 for (i=0; i < n; i++)
154 short_swap(wp(p + 30 + (i * 2)));
155 p += 30 + ((n&~1)+1)*2;
161 vms_vector_swap(vp(p + 4));
162 vms_vector_swap(vp(p + 16));
164 uvl_val = (g3s_uvl *)((p+30+((n&~1)+1)*2) + (i * sizeof(g3s_uvl)));
165 fix_swap(&uvl_val->u);
166 fix_swap(&uvl_val->v);
168 short_swap(wp(p+28));
170 short_swap(wp(p + 30 + (i * 2)));
171 p += 30 + ((n&~1)+1)*2 + n*12;
175 vms_vector_swap(vp(p + 4));
176 vms_vector_swap(vp(p + 16));
177 short_swap(wp(p + 28));
178 short_swap(wp(p + 30));
179 swap_polygon_model_data(p + w(p+28));
180 swap_polygon_model_data(p + w(p+30));
185 vms_vector_swap(vp(p + 20));
186 vms_vector_swap(vp(p + 4));
188 fix_swap(fp(p + 16));
189 fix_swap(fp(p + 32));
195 vms_vector_swap(vp(p+4));
196 short_swap(wp(p+16));
197 swap_polygon_model_data(p + w(p+16));
202 short_swap(wp(p + 2));
207 Error("invalid polygon model\n"); //Int3();
214 #ifdef WORDS_NEED_ALIGNMENT
215 void add_chunk(ubyte *old_base, ubyte *new_base, int offset,
216 chunk *chunk_list, int *no_chunks)
218 Assert(*no_chunks + 1 < MAX_CHUNKS); //increase MAX_CHUNKS if you get this
219 chunk_list[*no_chunks].old_base = old_base;
220 chunk_list[*no_chunks].new_base = new_base;
221 chunk_list[*no_chunks].offset = offset;
222 chunk_list[*no_chunks].correction = 0;
227 * finds what chunks the data points to, adds them to the chunk_list,
228 * and returns the length of the current chunk
230 int get_chunks(ubyte *data, ubyte *new_data, chunk *list, int *no)
235 while (INTEL_SHORT(w(p)) != OP_EOF) {
236 switch (INTEL_SHORT(w(p))) {
238 n = INTEL_SHORT(w(p+2));
239 p += n*sizeof(struct vms_vector) + 4;
242 n = INTEL_SHORT(w(p+2));
243 p += n*sizeof(struct vms_vector) + 8;
246 n = INTEL_SHORT(w(p+2));
247 p += 30 + ((n&~1)+1)*2;
250 n = INTEL_SHORT(w(p+2));
251 p += 30 + ((n&~1)+1)*2 + n*12;
254 add_chunk(p, p - data + new_data, 28, list, no);
255 add_chunk(p, p - data + new_data, 30, list, no);
262 add_chunk(p, p - data + new_data, 16, list, no);
269 Error("invalid polygon model\n");
274 #endif //def WORDS_NEED_ALIGNMENT
276 void verify(ubyte *data)
281 while (w(p) != OP_EOF) {
285 p += n*sizeof(struct vms_vector) + 4;
289 p += n*sizeof(struct vms_vector) + 8;
293 p += 30 + ((n&~1)+1)*2;
297 p += 30 + ((n&~1)+1)*2 + n*12;
300 verify(p + w(p + 28));
301 verify(p + w(p + 30));
308 verify(p + w(p + 16));
315 Error("invalid polygon model\n");
321 //calls the object interpreter to render an object. The object renderer
322 //is really a seperate pipeline. returns true if drew
323 bool g3_draw_polygon_model(void *model_ptr,grs_bitmap **model_bitmaps,vms_angvec *anim_angles,fix model_light,fix *glow_values)
325 ubyte *p = model_ptr;
327 glow_num = -1; //glow off by default
329 while (w(p) != OP_EOF)
336 rotate_point_list(Interp_point_list,vp(p+4),n);
337 p += n*sizeof(struct vms_vector) + 4;
342 case OP_DEFP_START: {
346 rotate_point_list(&Interp_point_list[s],vp(p+8),n);
347 p += n*sizeof(struct vms_vector) + 8;
355 Assert( nv < MAX_POINTS_PER_POLY );
356 if (g3_check_normal_facing(vp(p+4),vp(p+16)) > 0) {
364 // DPH: Now we treat this color as 15bpp
365 // gr_setcolor(w(p+28));
367 #ifndef FADE_FLATPOLY
368 gr_setcolor(gr_find_closest_color_15bpp(w(p + 28)));
370 //l = (32 * model_light) >> 16;
371 l = f2i(fixmul(i2f(32), model_light));
373 else if (l>32) l = 32;
374 cc = gr_find_closest_color_15bpp(w(p+28));
375 c = gr_fade_table[(l<<8)|cc];
380 point_list[i] = Interp_point_list + wp(p+30)[i];
382 g3_draw_poly(nv,point_list);
385 p += 30 + ((nv&~1)+1)*2;
394 Assert( nv < MAX_POINTS_PER_POLY );
395 if (g3_check_normal_facing(vp(p+4),vp(p+16)) > 0) {
399 //calculate light from surface normal
401 if (glow_num < 0) { //no glow
403 light = -vm_vec_dot(&View_matrix.fvec,vp(p+16));
404 light = f1_0/4 + (light*3)/4;
405 light = fixmul(light,model_light);
408 light = glow_values[glow_num];
412 //now poke light into l values
414 uvl_list = (g3s_uvl *) (p+30+((nv&~1)+1)*2);
417 uvl_list[i].l = light;
420 point_list[i] = Interp_point_list + wp(p+30)[i];
422 g3_draw_tmap(nv,point_list,uvl_list,model_bitmaps[w(p+28)]);
425 p += 30 + ((nv&~1)+1)*2 + nv*12;
432 if (g3_check_normal_facing(vp(p+16),vp(p+4)) > 0) { //facing
434 //draw back then front
436 g3_draw_polygon_model(p+w(p+30),model_bitmaps,anim_angles,model_light,glow_values);
437 g3_draw_polygon_model(p+w(p+28),model_bitmaps,anim_angles,model_light,glow_values);
440 else { //not facing. draw front then back
442 g3_draw_polygon_model(p+w(p+28),model_bitmaps,anim_angles,model_light,glow_values);
443 g3_draw_polygon_model(p+w(p+30),model_bitmaps,anim_angles,model_light,glow_values);
452 g3s_point rod_bot_p,rod_top_p;
454 g3_rotate_point(&rod_bot_p,vp(p+20));
455 g3_rotate_point(&rod_top_p,vp(p+4));
457 g3_draw_rod_tmap(model_bitmaps[w(p+2)],&rod_bot_p,w(p+16),&rod_top_p,w(p+32),f1_0);
467 a = &anim_angles[w(p+2)];
471 g3_start_instance_angles(vp(p+4),a);
473 g3_draw_polygon_model(p+w(p+16),model_bitmaps,anim_angles,model_light,glow_values);
491 Error("invalid polygon model\n");
500 //alternate interpreter for morphing object
501 bool g3_draw_morphing_model(void *model_ptr,grs_bitmap **model_bitmaps,vms_angvec *anim_angles,fix model_light,vms_vector *new_points)
503 ubyte *p = model_ptr;
504 fix *glow_values = NULL;
506 glow_num = -1; //glow off by default
508 while (w(p) != OP_EOF)
515 rotate_point_list(Interp_point_list,new_points,n);
516 p += n*sizeof(struct vms_vector) + 4;
521 case OP_DEFP_START: {
525 rotate_point_list(&Interp_point_list[s],new_points,n);
526 p += n*sizeof(struct vms_vector) + 8;
535 gr_setcolor(w(p+28));
538 point_list[i] = Interp_point_list + wp(p+30)[i];
540 for (ntris=nv-2;ntris;ntris--) {
542 point_list[2] = Interp_point_list + wp(p+30)[i++];
544 g3_check_and_draw_poly(3,point_list,NULL,NULL);
546 point_list[1] = point_list[2];
550 p += 30 + ((nv&~1)+1)*2;
558 g3s_uvl morph_uvls[3];
562 //calculate light from surface normal
564 if (glow_num < 0) { //no glow
566 light = -vm_vec_dot(&View_matrix.fvec,vp(p+16));
567 light = f1_0/4 + (light*3)/4;
568 light = fixmul(light,model_light);
571 light = glow_values[glow_num];
575 //now poke light into l values
577 uvl_list = (g3s_uvl *) (p+30+((nv&~1)+1)*2);
580 morph_uvls[i].l = light;
583 point_list[i] = Interp_point_list + wp(p+30)[i];
585 morph_uvls[i].u = uvl_list[i].u;
586 morph_uvls[i].v = uvl_list[i].v;
589 for (ntris=nv-2;ntris;ntris--) {
591 point_list[2] = Interp_point_list + wp(p+30)[i];
592 morph_uvls[2].u = uvl_list[i].u;
593 morph_uvls[2].v = uvl_list[i].v;
596 g3_check_and_draw_tmap(3,point_list,uvl_list,model_bitmaps[w(p+28)],NULL,NULL);
598 point_list[1] = point_list[2];
599 morph_uvls[1].u = morph_uvls[2].u;
600 morph_uvls[1].v = morph_uvls[2].v;
604 p += 30 + ((nv&~1)+1)*2 + nv*12;
611 if (g3_check_normal_facing(vp(p+16),vp(p+4)) > 0) { //facing
613 //draw back then front
615 g3_draw_morphing_model(p+w(p+30),model_bitmaps,anim_angles,model_light,new_points);
616 g3_draw_morphing_model(p+w(p+28),model_bitmaps,anim_angles,model_light,new_points);
619 else { //not facing. draw front then back
621 g3_draw_morphing_model(p+w(p+28),model_bitmaps,anim_angles,model_light,new_points);
622 g3_draw_morphing_model(p+w(p+30),model_bitmaps,anim_angles,model_light,new_points);
631 g3s_point rod_bot_p,rod_top_p;
633 g3_rotate_point(&rod_bot_p,vp(p+20));
634 g3_rotate_point(&rod_top_p,vp(p+4));
636 g3_draw_rod_tmap(model_bitmaps[w(p+2)],&rod_bot_p,w(p+16),&rod_top_p,w(p+32),f1_0);
646 a = &anim_angles[w(p+2)];
650 g3_start_instance_angles(vp(p+4),a);
652 g3_draw_polygon_model(p+w(p+16),model_bitmaps,anim_angles,model_light,glow_values);
673 void init_model_sub(ubyte *p)
675 Assert(++nest_count < 1000);
677 while (w(p) != OP_EOF) {
683 p += n*sizeof(struct vms_vector) + 4;
687 case OP_DEFP_START: {
689 p += n*sizeof(struct vms_vector) + 8;
696 Assert(nv > 2); //must have 3 or more points
698 // *wp(p+28) = (short)gr_find_closest_color_15bpp(w(p+28));
700 p += 30 + ((nv&~1)+1)*2;
708 Assert(nv > 2); //must have 3 or more points
710 if (w(p+28) > highest_texture_num)
711 highest_texture_num = w(p+28);
713 p += 30 + ((nv&~1)+1)*2 + nv*12;
720 init_model_sub(p+w(p+28));
721 init_model_sub(p+w(p+30));
733 init_model_sub(p+w(p+16));
743 Error("invalid polygon model\n");
748 //init code for bitmap models
749 void g3_init_polygon_model(void *model_ptr)
755 highest_texture_num = -1;
757 init_model_sub((ubyte *) model_ptr);
760 //uninit code for bitmap models
761 void g3_uninit_polygon_model(void *model_ptr)
763 // not required, the above g3_init_polygon_model doesn't change the data