Disabled shading of flat (non-textured) polygons. Fixes laser and plasma lighting...
[btb/d2x.git] / 3d / interp.c
index effa100..bd5c18e 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: interp.c,v 1.8 2002-10-28 20:57:11 btb Exp $ */
+/* $Id: interp.c,v 1.17 2005-03-16 01:56:24 btb Exp $ */
 /*
 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
 SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
@@ -16,23 +16,6 @@ COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
  *
  * Polygon object interpreter
  *
- * Old Log:
- * Revision 1.4  1995/10/10  22:20:09  allender
- * new morphing code from Matt
- *
- * Revision 1.3  1995/08/31  15:40:24  allender
- * swap color data correctly
- *
- * Revision 1.2  1995/05/11  13:06:38  allender
- * fix int --> short problem
- *
- * Revision 1.1  1995/05/05  08:51:41  allender
- * Initial revision
- *
- * Revision 1.1  1995/04/17  06:44:33  matt
- * Initial revision
- *
- *
  */
 
 #ifdef HAVE_CONFIG_H
@@ -40,16 +23,17 @@ COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
 #endif
 
 #ifdef RCS
-static char rcsid[] = "$Id: interp.c,v 1.8 2002-10-28 20:57:11 btb Exp $";
+static char rcsid[] = "$Id: interp.c,v 1.17 2005-03-16 01:56:24 btb Exp $";
 #endif
 
 #include <stdlib.h>
 #include "error.h"
 
-#include "3d.h"
+#include "interp.h"
 #include "globvars.h"
 #include "gr.h"
 #include "byteswap.h"
+#include "u_mem.h"
 
 #define OP_EOF          0   //eof
 #define OP_DEFPOINTS    1   //defpoints
@@ -61,7 +45,7 @@ static char rcsid[] = "$Id: interp.c,v 1.8 2002-10-28 20:57:11 btb Exp $";
 #define OP_DEFP_START   7   //defpoints with start
 #define OP_GLOW         8   //glow value for next poly
 
-#define N_OPCODES (sizeof(opcode_table) / sizeof(*opcode_table))
+//#define N_OPCODES (sizeof(opcode_table) / sizeof(*opcode_table))
 
 #define MAX_POINTS_PER_POLY 25
 
@@ -85,6 +69,7 @@ void g3_set_interp_points(g3s_point *pointlist)
 
 #define w(p)  (*((short *) (p)))
 #define wp(p)  ((short *) (p))
+#define fp(p)  ((fix *) (p))
 #define vp(p)  ((vms_vector *) (p))
 
 void rotate_point_list(g3s_point *dest,vms_vector *src,int n)
@@ -105,11 +90,28 @@ void short_swap(short *s)
        *s = SWAPSHORT(*s);
 }
 
+void fix_swap(fix *f)
+{
+       *f = (fix)SWAPINT((int)*f);
+}
+
 void vms_vector_swap(vms_vector *v)
 {
-       v->x = (fix)SWAPINT((int)v->x);
-       v->y = (fix)SWAPINT((int)v->y);
-       v->z = (fix)SWAPINT((int)v->z);
+       fix_swap(fp(&v->x));
+       fix_swap(fp(&v->y));
+       fix_swap(fp(&v->z));
+}
+
+void fixang_swap(fixang *f)
+{
+       *f = (fixang)SWAPSHORT((short)*f);
+}
+
+void vms_angvec_swap(vms_angvec *v)
+{
+       fixang_swap(&v->p);
+       fixang_swap(&v->b);
+       fixang_swap(&v->h);
 }
 
 void swap_polygon_model_data(ubyte *data)
@@ -165,8 +167,8 @@ void swap_polygon_model_data(ubyte *data)
                                vms_vector_swap(vp(p + 16));
                                for (i=0;i<n;i++) {
                                        uvl_val = (g3s_uvl *)((p+30+((n&~1)+1)*2) + (i * sizeof(g3s_uvl)));
-                                       uvl_val->u = (fix)SWAPINT((int)uvl_val->u);
-                                       uvl_val->v = (fix)SWAPINT((int)uvl_val->v);
+                                       fix_swap(&uvl_val->u);
+                                       fix_swap(&uvl_val->v);
                                }
                                short_swap(wp(p+28));
                                for (i=0;i<n;i++)
@@ -188,8 +190,8 @@ void swap_polygon_model_data(ubyte *data)
                                vms_vector_swap(vp(p + 20));
                                vms_vector_swap(vp(p + 4));
                                short_swap(wp(p+2));
-                               *((int *)(p + 16)) = SWAPINT(*((int *)(p + 16)));
-                               *((int *)(p + 32)) = SWAPINT(*((int *)(p + 32)));
+                               fix_swap(fp(p + 16));
+                               fix_swap(fp(p + 32));
                                p+=36;
                                break;
 
@@ -207,13 +209,120 @@ void swap_polygon_model_data(ubyte *data)
                                break;
 
                        default:
-                               Int3();
+                               Error("invalid polygon model\n"); //Int3();
                }
                short_swap(wp(p));
        }
 }
 #endif
 
+#ifdef WORDS_NEED_ALIGNMENT
+void add_chunk(ubyte *old_base, ubyte *new_base, int offset,
+              chunk *chunk_list, int *no_chunks)
+{
+       Assert(*no_chunks + 1 < MAX_CHUNKS); //increase MAX_CHUNKS if you get this
+       chunk_list[*no_chunks].old_base = old_base;
+       chunk_list[*no_chunks].new_base = new_base;
+       chunk_list[*no_chunks].offset = offset;
+       chunk_list[*no_chunks].correction = 0;
+       (*no_chunks)++;
+}
+
+/*
+ * finds what chunks the data points to, adds them to the chunk_list, 
+ * and returns the length of the current chunk
+ */
+int get_chunks(ubyte *data, ubyte *new_data, chunk *list, int *no)
+{
+       short n;
+       ubyte *p = data;
+
+       while (INTEL_SHORT(w(p)) != OP_EOF) {
+               switch (INTEL_SHORT(w(p))) {
+               case OP_DEFPOINTS:
+                       n = INTEL_SHORT(w(p+2));
+                       p += n*sizeof(struct vms_vector) + 4;
+                       break;
+               case OP_DEFP_START:
+                       n = INTEL_SHORT(w(p+2));
+                       p += n*sizeof(struct vms_vector) + 8;
+                       break;
+               case OP_FLATPOLY:
+                       n = INTEL_SHORT(w(p+2));
+                       p += 30 + ((n&~1)+1)*2;
+                       break;
+               case OP_TMAPPOLY:
+                       n = INTEL_SHORT(w(p+2));
+                       p += 30 + ((n&~1)+1)*2 + n*12;
+                       break;
+               case OP_SORTNORM:
+                       add_chunk(p, p - data + new_data, 28, list, no);
+                       add_chunk(p, p - data + new_data, 30, list, no);
+                       p += 32;
+                       break;
+               case OP_RODBM:
+                       p+=36;
+                       break;
+               case OP_SUBCALL:
+                       add_chunk(p, p - data + new_data, 16, list, no);
+                       p+=20;
+                       break;
+               case OP_GLOW:
+                       p += 4;
+                       break;
+               default:
+                       Error("invalid polygon model\n");
+               }
+       }
+       return p + 2 - data;
+}
+#endif //def WORDS_NEED_ALIGNMENT
+
+void verify(ubyte *data)
+{
+       short n;
+       ubyte *p = data;
+
+       while (w(p) != OP_EOF) {
+               switch (w(p)) {
+               case OP_DEFPOINTS:
+                       n = (w(p+2));
+                       p += n*sizeof(struct vms_vector) + 4;
+                       break;
+               case OP_DEFP_START:
+                       n = (w(p+2));
+                       p += n*sizeof(struct vms_vector) + 8;
+                       break;
+               case OP_FLATPOLY:
+                       n = (w(p+2));
+                       p += 30 + ((n&~1)+1)*2;
+                       break;
+               case OP_TMAPPOLY:
+                       n = (w(p+2));
+                       p += 30 + ((n&~1)+1)*2 + n*12;
+                       break;
+               case OP_SORTNORM:
+                       verify(p + w(p + 28));
+                       verify(p + w(p + 30));
+                       p += 32;
+                       break;
+               case OP_RODBM:
+                       p+=36;
+                       break;
+               case OP_SUBCALL:
+                       verify(p + w(p + 16));
+                       p+=20;
+                       break;
+               case OP_GLOW:
+                       p += 4;
+                       break;
+               default:
+                       Error("invalid polygon model\n");
+               }
+       }
+}
+
+
 //calls the object interpreter to render an object.  The object renderer
 //is really a seperate pipeline. returns true if drew
 bool g3_draw_polygon_model(void *model_ptr,grs_bitmap **model_bitmaps,vms_angvec *anim_angles,fix model_light,fix *glow_values)
@@ -251,13 +360,18 @@ bool g3_draw_polygon_model(void *model_ptr,grs_bitmap **model_bitmaps,vms_angvec
                                Assert( nv < MAX_POINTS_PER_POLY );
                                if (g3_check_normal_facing(vp(p+4),vp(p+16)) > 0) {
                                        int i;
+#ifdef FADE_FLATPOLY
                                        short c;
                                        unsigned char cc;
                                        int l;
+#endif
 
 //                                     DPH: Now we treat this color as 15bpp
 //                                     gr_setcolor(w(p+28));
                                        
+#ifndef FADE_FLATPOLY
+                                       gr_setcolor(gr_find_closest_color_15bpp(w(p + 28)));
+#else
                                        //l = (32 * model_light) >> 16;
                                        l = f2i(fixmul(i2f(32), model_light));
                                        if (l<0) l = 0;
@@ -265,6 +379,7 @@ bool g3_draw_polygon_model(void *model_ptr,grs_bitmap **model_bitmaps,vms_angvec
                                        cc = gr_find_closest_color_15bpp(w(p+28));
                                        c = gr_fade_table[(l<<8)|cc];
                                        gr_setcolor(c);
+#endif
 
                                        for (i=0;i<nv;i++)
                                                point_list[i] = Interp_point_list + wp(p+30)[i];
@@ -378,13 +493,11 @@ bool g3_draw_polygon_model(void *model_ptr,grs_bitmap **model_bitmaps,vms_angvec
                                break;
 
                        default:
-                       ;
+                               Error("invalid polygon model\n");
                }
        return 1;
 }
 
-extern int gr_find_closest_color_15bpp( int rgb );
-
 #ifndef NDEBUG
 int nest_count;
 #endif
@@ -631,8 +744,8 @@ void init_model_sub(ubyte *p)
                        case OP_GLOW:
                                p += 4;
                                break;
-                       default:
-                               Assert(0);
+                       default:
+                               Error("invalid polygon model\n");
                }
        }
 }
@@ -649,3 +762,9 @@ void g3_init_polygon_model(void *model_ptr)
        init_model_sub((ubyte *) model_ptr);
 }
 
+//uninit code for bitmap models
+void g3_uninit_polygon_model(void *model_ptr)
+{
+       // not required, the above g3_init_polygon_model doesn't change the data
+       model_ptr = model_ptr;
+}