From c068f22329d5cc722622a2183bbb22eef2093df7 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 24 Aug 2026 11:16:07 +0200 Subject: initial import --- src/parsec/obj_iter.cpp | 1357 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1357 insertions(+) create mode 100644 src/parsec/obj_iter.cpp (limited to 'src/parsec/obj_iter.cpp') diff --git a/src/parsec/obj_iter.cpp b/src/parsec/obj_iter.cpp new file mode 100644 index 0000000..9b047e5 --- /dev/null +++ b/src/parsec/obj_iter.cpp @@ -0,0 +1,1357 @@ +/* + * PARSEC - Attached Iter Polygons + * + * $Author: uberlinuxguy $ - $Date: 2004/09/26 03:43:35 $ + * + * Orginally written by: + * Copyright (c) Markus Hadwiger 1999-2001 + * Copyright (c) Michael Woegerbauer 1999-2000 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +// C library +#include +#include +#include + +// compilation flags/debug support +#include "config.h" +#include "debug.h" + +// general definitions +#include "general.h" +#include "objstruc.h" +#include "od_class.h" + +// global externals +#include "globals.h" + +// drawing subsystem +#include "d_iter.h" + +// mathematics header +#include "utl_math.h" + +// model header +#include "utl_model.h" + +// local module header +#include "obj_iter.h" + +// proprietary module headers +#include "obj_clas.h" +#include "obj_creg.h" +#include "obj_game.h" +#include "obj_name.h" +#include "part_api.h" +#include "part_def.h" + + + +// macro to ease dynamic vertex and triangle definition ----------------------- +// +#define SET_VTX( n, X1, Y1, Z1, R1, G1, B1, A1 ) \ + itprim.Vtxs[ n ].X = FLOAT_TO_GEOMV( (X1) + (OBJITEROFS_X) ); \ + itprim.Vtxs[ n ].Y = FLOAT_TO_GEOMV( (Y1) + (OBJITEROFS_Y) ); \ + itprim.Vtxs[ n ].Z = FLOAT_TO_GEOMV( (Z1) + (OBJITEROFS_Z) ); \ + itprim.Vtxs[ n ].R = R1; \ + itprim.Vtxs[ n ].G = G1; \ + itprim.Vtxs[ n ].B = B1; \ + itprim.Vtxs[ n ].A = A1; + + +// limit length of thrust to maximum speed in case of active afterburner ------ +// +#define GET_SPEED() \ + ( ( shippo->CurSpeed == AFTERBURNER_SPEED ) ? \ + shippo->MaxSpeed : shippo->CurSpeed ) + + +// yellow thrust polygons if afterburner active ------------------------------- +// +#define CHECK_AFTERBURNER_COLOR() \ + if ( shippo->CurSpeed == AFTERBURNER_SPEED ) { \ + apex_r ^= apex_b; \ + apex_b ^= apex_r; \ + apex_r ^= apex_b; \ + base_r ^= base_b; \ + base_b ^= base_r; \ + base_r ^= base_b; \ + } + + +// fixed offset to hard-coded coordinate specification ------------------------ +// +#define OBJITEROFS_X 0.0 +#define OBJITEROFS_Y 0.0 +#define OBJITEROFS_Z 0.0 + + +// attach dynamic iter polygons to firebird ----------------------------------- +// +PRIVATE +void AttachIterPolysFirebird( GenObject *obj, int inorder ) +{ + ASSERT( obj != NULL ); + ASSERT( OBJECT_TYPE_SHIP( obj ) ); + + // only immediately after the object is drawn + if ( !inorder ) { + return; + } + + ShipObject *shippo = (ShipObject *) obj; + + // setup transformation matrix + D_LoadIterMatrix( shippo->CurrentXmatrx ); + + IterTriangle3 itprim; + itprim.flags = ITERFLAG_Z_DIV_XYZ | ITERFLAG_Z_TO_DEPTH; + itprim.itertype = iter_rgba | iter_additiveblend; + itprim.raststate = rast_nozwrite; + itprim.rastmask = rast_mask_zcompare; + + int rand8 = RAND() % 20; + float pbase = ( (float)GET_SPEED() / 2440.0 ); + float Param1 = -8.8 - pbase + ( RAND() % ( (int)pbase + 1 ) ) / 10.0; + float Param2 = -8.8 - pbase + ( RAND() % ( (int)pbase + 1 ) ) / 10.0; + float Param3 = -8.8 - pbase + ( RAND() % ( (int)pbase + 1 ) ) / 10.0; + float Param4 = -8.8 - pbase + ( RAND() % ( (int)pbase + 1 ) ) / 10.0; + + byte apex_r = 10 + rand8; + byte apex_g = 20 + rand8; + byte apex_b = 205 + rand8; + byte apex_a = 10 + rand8; + + byte base_r = 140 + rand8; + byte base_g = 140 + rand8; + byte base_b = 180 + rand8; + byte base_a = 96 + rand8; + + // change color of thrust polygons if afterburner active + CHECK_AFTERBURNER_COLOR(); + + // first -------------------------------------------- + SET_VTX( 0, 10.05, -0.3, -9.0, base_r, base_g, base_b, base_a ); + SET_VTX( 1, 11, -2.5, Param1, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, 7.6, -5.0, -6.8, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, 23.1, -0.3, -6.9, base_r, base_g, base_b, base_a ); + SET_VTX( 1, 11, -2.5, Param1, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, 7.6, -5.0, -6.8, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, 23.1, -0.3, -6.9, base_r, base_g, base_b, base_a ); + SET_VTX( 1, 11, -2.5, Param1, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, 10.05, -0.3, -9.0, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + // second -------------------------------------------- + SET_VTX( 0, 10.05, 0.3, -9.0, base_r, base_g, base_b, base_a ); + SET_VTX( 1, 11, 2.5, Param2, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, 7.6, 5.0, -6.8, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, 23.1, 0.3, -6.9, base_r, base_g, base_b, base_a ); + SET_VTX( 1, 11, 2.5, Param2, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, 7.6, 5.0, -6.8, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, 23.1, 0.3, -6.9, base_r, base_g, base_b, base_a ); + SET_VTX( 1, 11, 2.5, Param2, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, 10.05, 0.3, -9.0, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + // third ------ + SET_VTX( 0, -7.9, -0.3, -8.8, base_r, base_g, base_b, base_a ); + SET_VTX( 1, -8.0, -3.1, Param3, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, -5.4, -5.0, -6.9, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, -21, -0.3, -6.9, base_r, base_g, base_b, base_a ); + SET_VTX( 1, -8.0, -3.1, Param3, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, -5.4, -5.0, -6.9, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, -21, -0.3, -6.9, base_r, base_g, base_b, base_a ); + SET_VTX( 1, -8.0, -3.1, Param3, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, -7.9, -0.3, -8.8, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + // forth ------ + SET_VTX( 0, -7.9, 0.3, -8.8, base_r, base_g, base_b, base_a ); + SET_VTX( 1, -8.0, 3.1, Param4, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, -5.4, 5.0, -6.9, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, -21, 0.3, -6.9, base_r, base_g, base_b, base_a ); + SET_VTX( 1, -8.0, 3.1, Param4, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, -5.4, 5.0, -6.9, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, -21, 0.3, -6.9, base_r, base_g, base_b, base_a ); + SET_VTX( 1, -8.0, 3.1, Param4, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, -7.9, 0.3, -8.8, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + // restore identity transformation + D_LoadIterMatrix( NULL ); +} + + +// fixed offset to hard-coded coordinate specification ------------------------ +// +#undef OBJITEROFS_X +#undef OBJITEROFS_Y +#undef OBJITEROFS_Z +#define OBJITEROFS_X 0.0 +#define OBJITEROFS_Y 0.0 +#define OBJITEROFS_Z 0.0 + + +// attach dynamic iter polygons to bluespire ---------------------------------- +// +PRIVATE +void AttachIterPolysBluespire( GenObject *obj, int inorder ) +{ + ASSERT( obj != NULL ); + ASSERT( OBJECT_TYPE_SHIP( obj ) ); + + // only immediately after the object is drawn + if ( !inorder ) { + return; + } + + ShipObject *shippo = (ShipObject *) obj; + + // setup transformation matrix + D_LoadIterMatrix( shippo->CurrentXmatrx ); + + IterTriangle3 itprim; + itprim.flags = ITERFLAG_Z_DIV_XYZ | ITERFLAG_Z_TO_DEPTH; + itprim.itertype = iter_rgba | iter_additiveblend; + itprim.raststate = rast_nozwrite; + itprim.rastmask = rast_mask_zcompare; + + int rand8 = RAND() % 20; + float pbase = ( (float)GET_SPEED() / 2440.0 ); + float Param1 = -14 - pbase + ( RAND() % ( (int)pbase + 1 ) ) / 10.0; + float Param3 = -14 - pbase + ( RAND() % ( (int)pbase + 1 ) ) / 10.0; + float Param2 = -15 - pbase + ( RAND() % ( (int)pbase + 1 ) ) / 10.0; + + byte apex_r = 20 + rand8; + byte apex_g = 60 + rand8; + byte apex_b = 210 + rand8; + byte apex_a = 0 + rand8 / 2; + + byte base_r = 180 + rand8; + byte base_g = 180 + rand8; + byte base_b = 180 + rand8; + byte base_a = 96 + rand8; + + // change color of thrust polygons if afterburner active + CHECK_AFTERBURNER_COLOR(); + + SET_VTX( 0, 3.4, -0.35, -12.8, base_r, base_g, base_b, base_a ); + SET_VTX( 1, 2.5, -1.3,Param1, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, 3.4, -2.25, -12.8, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, 3.4, -0.35, -12.8, base_r, base_g, base_b, base_a ); + SET_VTX( 1, 2.5, -1.3,Param1, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, -3.5, -0.35, -12.8, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, -2.6, -1.3,Param3, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 1, 2.5, -1.3,Param1, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, -3.5, -0.35, -12.8, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, -3.5, -0.35, -12.8, base_r, base_g, base_b, base_a ); + SET_VTX( 1, -2.6, -1.3,Param3, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, -3.5, -2.25, -12.8, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, -2.6, -1.3,Param3, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 1, 2.5, -1.3,Param1, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, -3.5, -2.25, -12.8, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, 3.4, -2.25, -12.8, base_r, base_g, base_b, base_a ); + SET_VTX( 1, 2.5, -1.3,Param1, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, -3.5, -2.25, -12.8, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + // right -------------------------------------------- + SET_VTX( 0, 17.7, 0.8, -13.8, base_r, base_g, base_b, base_a ); + SET_VTX( 1, 16.2, 1.9,Param2, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, 17.7, 3.0, -13.8, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, 15.7, 0.0, -13.8, base_r, base_g, base_b, base_a ); + SET_VTX( 1, 16.2, 1.9,Param2, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, 17.7, 0.8, -13.8, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, 15.7, 0.0, -13.8, base_r, base_g, base_b, base_a ); + SET_VTX( 1, 16.2, 1.9,Param2, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, 14.2, 1.9, -13.8, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, 14.2, 1.9, -13.8, base_r, base_g, base_b, base_a ); + SET_VTX( 1, 16.2, 1.9,Param2, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, 15.7, 3.8, -13.8, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, 17.7, 3.0, -13.8, base_r, base_g, base_b, base_a ); + SET_VTX( 1, 16.2, 1.9,Param2, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, 15.7, 3.8, -13.8, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + // left -------------------------------------------- + SET_VTX( 0, -17.2, 0.8, -13.8, base_r, base_g, base_b, base_a ); + SET_VTX( 1, -15.7, 1.9,Param2, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, -17.2, 3.0, -13.8, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, -15.2, 0.0, -13.8, base_r, base_g, base_b, base_a ); + SET_VTX( 1, -15.7, 1.9,Param2, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, -17.2, 0.8, -13.8, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, -15.2, 0.0, -13.8, base_r, base_g, base_b, base_a ); + SET_VTX( 1, -15.7, 1.9,Param2, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, -13.7, 1.9, -13.8, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, -13.7, 1.9, -13.8, base_r, base_g, base_b, base_a ); + SET_VTX( 1, -15.7, 1.9,Param2, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, -15.2, 3.8, -13.8, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, -17.2, 3.0, -13.8, base_r, base_g, base_b, base_a ); + SET_VTX( 1, -15.7, 1.9,Param2, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, -15.2, 3.8, -13.8, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + // restore identity transformation + D_LoadIterMatrix( NULL ); +} + + +// fixed offset to hard-coded coordinate specification ------------------------ +// +#undef OBJITEROFS_X +#undef OBJITEROFS_Y +#undef OBJITEROFS_Z +#define OBJITEROFS_X 0.0 +#define OBJITEROFS_Y 0.0 +#define OBJITEROFS_Z 0.0 + + +// attach dynamic iter polygons to cormoran ----------------------------------- +// +PRIVATE +void AttachIterPolysCormoran( GenObject *obj, int inorder ) +{ + ASSERT( obj != NULL ); + ASSERT( OBJECT_TYPE_SHIP( obj ) ); + + // only immediately after the object is drawn + if ( !inorder ) { + return; + } + + ShipObject *shippo = (ShipObject *) obj; + + // setup transformation matrix + D_LoadIterMatrix( shippo->CurrentXmatrx ); + + IterTriangle3 itprim; + itprim.flags = ITERFLAG_Z_DIV_XYZ | ITERFLAG_Z_TO_DEPTH; + itprim.itertype = iter_rgba | iter_additiveblend /* | iter_specularadd*/; + itprim.raststate = rast_nozwrite; + itprim.rastmask = rast_mask_zcompare; + + int rand8 = RAND() % 20; + float pbase = ( (float)GET_SPEED() / 2440.0 ); + float Param = -6 - pbase + ( RAND() % ( (int)pbase + 1 ) ) / 10.0; + + byte apex_r = 20 + rand8; + byte apex_g = 150 + rand8; + byte apex_b = 235 + rand8; + byte apex_a = 0 + rand8 / 2; + + byte base_r = 220 + rand8; + byte base_g = 220 + rand8; + byte base_b = 235 + rand8; + byte base_a = 80 + rand8; + + // change color of thrust polygons if afterburner active + CHECK_AFTERBURNER_COLOR(); + + SET_VTX( 0, 1.0, -1.4, -5.0, base_r, base_g, base_b, base_a ); + SET_VTX( 1, 0.0, -3.0, Param, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, -1.0, -1.4, -5.0, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, 1.9, -3.0, -5.0, base_r, base_g, base_b, base_a ); + SET_VTX( 1, 0.0, -3.0, Param, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, 1.0, -1.4, -5.0, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, 1.0, -4.7, -5.0, base_r, base_g, base_b, base_a ); + SET_VTX( 1, 0.0, -3.0, Param, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, 1.9, -3.0, -5.0, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, -1.0, -4.7, -5.0, base_r, base_g, base_b, base_a ); + SET_VTX( 1, 0.0, -3.0, Param, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, 1.0, -4.7, -5.0, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, -1.9, -3.0, -5.0, base_r, base_g, base_b, base_a ); + SET_VTX( 1, 0.0, -3.0, Param, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, -1.0, -4.7, -5.0, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, -1.0, -1.4, -5.0, base_r, base_g, base_b, base_a ); + SET_VTX( 1, 0.0, -3.0, Param, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, -1.9, -3.0, -5.0, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + // restore identity transformation + D_LoadIterMatrix( NULL ); +} + + +// fixed offset to hard-coded coordinate specification ------------------------ +// +#undef OBJITEROFS_X +#undef OBJITEROFS_Y +#undef OBJITEROFS_Z +#define OBJITEROFS_X 0.0 +#define OBJITEROFS_Y 0.0 +#define OBJITEROFS_Z 0.0 + + +// attach dynamic iter polygons to stingray ----------------------------------- +// +PRIVATE +void AttachIterPolysStingray( GenObject *obj, int inorder ) +{ + ASSERT( obj != NULL ); + ASSERT( OBJECT_TYPE_SHIP( obj ) ); + + // only immediately after the object is drawn + if ( !inorder ) { + return; + } + + ShipObject *shippo = (ShipObject *) obj; + + // setup transformation matrix + D_LoadIterMatrix( shippo->CurrentXmatrx ); + + IterTriangle3 itprim; + itprim.flags = ITERFLAG_Z_DIV_XYZ | ITERFLAG_Z_TO_DEPTH; + itprim.itertype = iter_rgba | iter_additiveblend; + itprim.raststate = rast_nozwrite; + itprim.rastmask = rast_mask_zcompare; + + int rand8 = RAND() % 20; + float pbase = ( (float)GET_SPEED() / 2440.0 ); + float Param1 = -26.0 - pbase + ( RAND() % ( (int)pbase + 1 ) ) / 10.0; + float Param2 = -26.0 - pbase + ( RAND() % ( (int)pbase + 1 ) ) / 10.0; + float Param3 = -10.0 - pbase + ( RAND() % ( (int)pbase + 1 ) ) / 10.0; + float Param4 = -11.0 - pbase + ( RAND() % ( (int)pbase + 1 ) ) / 10.0; + + byte apex_r = 10 + rand8; + byte apex_g = 20 + rand8; + byte apex_b = 205 + rand8; + byte apex_a = 10 + rand8; + + byte base_r = 140 + rand8; + byte base_g = 140 + rand8; + byte base_b = 180 + rand8; + byte base_a = 96 + rand8; + + // change color of thrust polygons if afterburner active + CHECK_AFTERBURNER_COLOR(); + + // first ------------------------------------------------------------ + SET_VTX( 0, 15.0, 1.7, -25.2, base_r, base_g, base_b, base_a ); + SET_VTX( 1, 15.5, 0.0, Param1, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, 15.0, -1.7, -25.2, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, 15.0, -1.7, -25.2, base_r, base_g, base_b, base_a ); + SET_VTX( 1, 15.5, 0.0, Param1, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, 17.9, 0.0, -23.3, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, 17.9, 0.0, -23.3, base_r, base_g, base_b, base_a ); + SET_VTX( 1, 15.5, 0.0, Param1, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, 15.0, 1.7, -25.2, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + // second ----------------------------------------------------------- + SET_VTX( 0, -15.0, 1.7, -25.2, base_r, base_g, base_b, base_a ); + SET_VTX( 1, -15.5, 0.0, Param2, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, -15.0, -1.7, -25.2, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, -15.0, -1.7, -25.2, base_r, base_g, base_b, base_a ); + SET_VTX( 1, -15.5, 0.0, Param2, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, -17.9, 0.0, -23.3, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, -17.9, 0.0, -23.3, base_r, base_g, base_b, base_a ); + SET_VTX( 1, -15.5, 0.0, Param2, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, -15.0, 1.7, -25.2, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + // third ------------------------------------------------------------ + SET_VTX( 0, -9.4, 2.4, -8.8, base_r, base_g, base_b, base_a ); + SET_VTX( 1, -6.5, 0.0, Param3, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, -9.4, -2.5, -8.8, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, -9.4, -2.5, -8.8, base_r, base_g, base_b, base_a ); + SET_VTX( 1, -6.5, 0.0, Param3, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, 0.0, -3.1, -8.8, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, 0.0, -3.1, -8.8, base_r, base_g, base_b, base_a ); + SET_VTX( 1, -6.5, 0.0, Param3, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, 0.0, 0.0, Param4, apex_r, apex_g, apex_b, apex_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, 0.0, 0.0, Param4, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 1, 6.5, 0.0, Param3, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, 0.0, -3.1, -8.8, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, 0.0, -3.1, -8.8, base_r, base_g, base_b, base_a ); + SET_VTX( 1, 6.5, 0.0, Param3, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, 9.3, -2.5, -8.8, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, 9.3, -2.5, -8.8, base_r, base_g, base_b, base_a ); + SET_VTX( 1, 6.5, 0.0, Param3, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, 9.3, 2.4, -8.8, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, 9.3, 2.4, -8.8, base_r, base_g, base_b, base_a ); + SET_VTX( 1, 6.5, 0.0, Param3, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, 0.0, 3.0, -8.8, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 2, 0.0, 3.0, -8.8, base_r, base_g, base_b, base_a ); + SET_VTX( 1, 6.5, 0.0, Param3, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 0, 0.0, 0.0, Param4, apex_r, apex_g, apex_b, apex_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 2, 0.0, 0.0, Param4, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 1, -6.5, 0.0, Param3, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 0, 0.0, 3.0, -8.8, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, 0.0, 3.0, -8.8, base_r, base_g, base_b, base_a ); + SET_VTX( 1, -6.5, 0.0, Param3, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, -9.4, 2.4, -8.8, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + // restore identity transformation + D_LoadIterMatrix( NULL ); +} + + +// fixed offset to hard-coded coordinate specification ------------------------ +// +#undef OBJITEROFS_X +#undef OBJITEROFS_Y +#undef OBJITEROFS_Z +#define OBJITEROFS_X 0.0 +#define OBJITEROFS_Y 0.0 +#define OBJITEROFS_Z 2.2 + + +// attach dynamic iter polygons to claymore ----------------------------------- +// +PRIVATE +void AttachIterPolysClaymore( GenObject *obj, int inorder ) +{ + ASSERT( obj != NULL ); + ASSERT( OBJECT_TYPE_SHIP( obj ) ); + + // only immediately after the object is drawn + if ( !inorder ) { + return; + } + + ShipObject *shippo = (ShipObject *) obj; + + // setup transformation matrix + D_LoadIterMatrix( shippo->CurrentXmatrx ); + + IterTriangle3 itprim; + itprim.flags = ITERFLAG_Z_DIV_XYZ | ITERFLAG_Z_TO_DEPTH; + itprim.itertype = iter_rgba | iter_additiveblend; + itprim.raststate = rast_nozwrite; + itprim.rastmask = rast_mask_zcompare; + + int rand8 = RAND() % 20; + float pbase = ( (float)GET_SPEED() / 2440.0 ); + float Param1 = -30.0 - pbase + ( RAND() % ( (int)pbase + 1 ) ) / 10.0; + float Param2 = -30.0 - pbase + ( RAND() % ( (int)pbase + 1 ) ) / 10.0; + + byte apex_r = 10 + rand8; + byte apex_g = 20 + rand8; + byte apex_b = 205 + rand8; + byte apex_a = 10 + rand8; + + byte base_r = 140 + rand8; + byte base_g = 140 + rand8; + byte base_b = 180 + rand8; + byte base_a = 96 + rand8; + + // change color of thrust polygons if afterburner active + CHECK_AFTERBURNER_COLOR(); + + // left -------------------------------------------------------------- + SET_VTX( 0, -11.0, -3.0, -29.0, base_r, base_g, base_b, base_a ); + SET_VTX( 1, -11.0, 0.0, Param1, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, -9.0, -2.0, -29.0, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, -9.0, -2.0, -29.0, base_r, base_g, base_b, base_a ); + SET_VTX( 1, -11.0, 0.0, Param1, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, -8.0, 0.0, -29.0, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, -8.0, 0.0, -29.0, base_r, base_g, base_b, base_a ); + SET_VTX( 1, -11.0, 0.0, Param1, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, -9.0, 2.0, -29.0, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, -9.0, 2.0, -29.0, base_r, base_g, base_b, base_a ); + SET_VTX( 1, -11.0, 0.0, Param1, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, -11.0, 3.0, -29.0, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, -11.0, 3.0, -29.0, base_r, base_g, base_b, base_a ); + SET_VTX( 1, -11.0, 0.0, Param1, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, -13.0, 2.0, -29.0, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, -13.0, 2.0, -29.0, base_r, base_g, base_b, base_a ); + SET_VTX( 1, -11.0, 0.0, Param1, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, -14.0, 0.0, -29.0, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, -14.0, 0.0, -29.0, base_r, base_g, base_b, base_a ); + SET_VTX( 1, -11.0, 0.0, Param1, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, -13.0, -2.0, -29.0, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, -13.0, -2.0, -29.0, base_r, base_g, base_b, base_a ); + SET_VTX( 1, -11.0, 0.0, Param1, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, -11.0, -3.0, -29.0, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + // right ------------------------------------------------------------- + SET_VTX( 0, 11.0, -3.0, -29.0, base_r, base_g, base_b, base_a ); + SET_VTX( 1, 11.0, 0.0, Param2, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, 9.0, -2.0, -29.0, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, 9.0, -2.0, -29.0, base_r, base_g, base_b, base_a ); + SET_VTX( 1, 11.0, 0.0, Param2, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, 8.0, 0.0, -29.0, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, 8.0, 0.0, -29.0, base_r, base_g, base_b, base_a ); + SET_VTX( 1, 11.0, 0.0, Param2, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, 9.0, 2.0, -29.0, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, 9.0, 2.0, -29.0, base_r, base_g, base_b, base_a ); + SET_VTX( 1, 11.0, 0.0, Param2, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, 11.0, 3.0, -29.0, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, 11.0, 3.0, -29.0, base_r, base_g, base_b, base_a ); + SET_VTX( 1, 11.0, 0.0, Param2, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, 13.0, 2.0, -29.0, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, 13.0, 2.0, -29.0, base_r, base_g, base_b, base_a ); + SET_VTX( 1, 11.0, 0.0, Param2, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, 14.0, 0.0, -29.0, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, 14.0, 0.0, -29.0, base_r, base_g, base_b, base_a ); + SET_VTX( 1, 11.0, 0.0, Param2, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, 13.0, -2.0, -29.0, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + SET_VTX( 0, 13.0, -2.0, -29.0, base_r, base_g, base_b, base_a ); + SET_VTX( 1, 11.0, 0.0, Param2, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, 11.0, -3.0, -29.0, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterTriangle3( &itprim, 0x3f ); + + // restore identity transformation + D_LoadIterMatrix( NULL ); +} + + +// fixed offset to hard-coded coordinate specification ------------------------ +// +#undef OBJITEROFS_X +#undef OBJITEROFS_Y +#undef OBJITEROFS_Z +#define OBJITEROFS_X 0.0 +#define OBJITEROFS_Y 0.0 +#define OBJITEROFS_Z 2.2 + + +// remember the subobject transformation for post-rendering ------------------- +// +static Xmatrx inorder_xmatrx; + + +// attach dynamic iter polygons to hurricane ---------------------------------- +// +PRIVATE +void AttachIterPolysHurricane( GenObject *obj, int inorder ) +{ + ASSERT( obj != NULL ); + ASSERT( OBJECT_TYPE_SHIP( obj ) ); + + // only attach to base object + if ( obj->ActiveVtxAnims > 0 ) { + ASSERT( obj->VtxAnimStates != NULL ); + dword *baseinfo = (dword *) &obj->VtxAnimStates[ obj->NumVtxAnims ]; + if ( baseinfo[ 0 ] != obj->NumVtxAnims ) { + return; + } + } + + // remember transformation for post-rendering the iter polys + if ( inorder ) { + memcpy( inorder_xmatrx, obj->CurrentXmatrx, sizeof( Xmatrx ) ); + return; + } + + ShipObject *shippo = (ShipObject *) obj; + + // setup transformation matrix + D_LoadIterMatrix( inorder_xmatrx ); + + IterRectangle3 itprim; + itprim.flags = ITERFLAG_Z_DIV_XYZ | ITERFLAG_Z_TO_DEPTH; + itprim.itertype = iter_rgba | iter_additiveblend; + itprim.raststate = rast_nozwrite; + itprim.rastmask = rast_mask_zcompare; + + int rand8 = RAND() % 20; + float pbase = ( (float)GET_SPEED() / 2440.0 ); + float Param = -30.0 - pbase + ( RAND() % ( (int)pbase + 1 ) ) / 10.0; + + byte apex_r = 10 + rand8; + byte apex_g = 20 + rand8; + byte apex_b = 205 + rand8; + byte apex_a = 10 + rand8; + + byte base_r = 140 + rand8; + byte base_g = 140 + rand8; + byte base_b = 180 + rand8; + byte base_a = 96 + rand8; + + // change color of thrust polygons if afterburner active + CHECK_AFTERBURNER_COLOR(); + + // upper thrust outlet ----------------------------------------------- + SET_VTX( 0, -6.5, -5.5, -30.0, base_r, base_g, base_b, base_a ); + SET_VTX( 1, -6.5, -5.5, Param, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, -6.5, -3.5, Param, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 3, -6.5, -3.5, -30.0, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterRectangle3( &itprim, 0x3f ); + + SET_VTX( 0, -6.5, -5.5, -30.0, base_r, base_g, base_b, base_a ); + SET_VTX( 1, -6.5, -5.5, Param, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, 6.5, -5.5, Param, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 3, 6.5, -5.5, -30.0, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterRectangle3( &itprim, 0x3f ); + + SET_VTX( 0, 6.5, -5.5, -30.0, base_r, base_g, base_b, base_a ); + SET_VTX( 1, 6.5, -5.5, Param, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, 6.5, -3.5, Param, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 3, 6.5, -3.5, -30.0, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterRectangle3( &itprim, 0x3f ); + + SET_VTX( 0, -6.5, -3.5, -30.0, base_r, base_g, base_b, base_a ); + SET_VTX( 1, -6.5, -3.5, Param, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, 6.5, -3.5, Param, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 3, 6.5, -3.5, -30.0, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterRectangle3( &itprim, 0x3f ); + + // lower thrust outlet ----------------------------------------------- + SET_VTX( 0, -6.5, 5.5, -30.0, base_r, base_g, base_b, base_a ); + SET_VTX( 1, -6.5, 5.5, Param, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, -6.5, 3.5, Param, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 3, -6.5, 3.5, -30.0, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterRectangle3( &itprim, 0x3f ); + + SET_VTX( 0, -6.5, 5.5, -30.0, base_r, base_g, base_b, base_a ); + SET_VTX( 1, -6.5, 5.5, Param, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, 6.5, 5.5, Param, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 3, 6.5, 5.5, -30.0, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterRectangle3( &itprim, 0x3f ); + + SET_VTX( 0, 6.5, 5.5, -30.0, base_r, base_g, base_b, base_a ); + SET_VTX( 1, 6.5, 5.5, Param, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, 6.5, 3.5, Param, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 3, 6.5, 3.5, -30.0, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterRectangle3( &itprim, 0x3f ); + + SET_VTX( 0, -6.5, 3.5, -30.0, base_r, base_g, base_b, base_a ); + SET_VTX( 1, -6.5, 3.5, Param, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 2, 6.5, 3.5, Param, apex_r, apex_g, apex_b, apex_a ); + SET_VTX( 3, 6.5, 3.5, -30.0, base_r, base_g, base_b, base_a ); + + // clip and draw polygon + D_DrawIterRectangle3( &itprim, 0x3f ); + + // restore identity transformation + D_LoadIterMatrix( NULL ); +} + + +// fixed offset to hard-coded coordinate specification ------------------------ +// +#undef OBJITEROFS_X +#undef OBJITEROFS_Y +#undef OBJITEROFS_Z +#define OBJITEROFS_X 0.0 +#define OBJITEROFS_Y 0.0 +#define OBJITEROFS_Z 0.0 + + +// iter polygon to object attachment functions -------------------------------- +// +PRIVATE +attach_iterpolys_fpt functab_attach_iterpolys[ MAX_DISTINCT_OBJCLASSES ]; + + +// attach dynamically generated iter polygons --------------------------------- +// +void OBJ_AttachIterPolygons( GenObject *obj, int inorder ) +{ + ASSERT( obj != NULL ); + ASSERT( obj->ObjectClass < (dword)NumObjClasses ); + + //NOTE: + // this function is called externally when an object is being rendered + // at the correct time to render dynamically attached polygons. + // e.g., by RO_OBJ::RO_RenderDynamicPolys(). + + // call attachment function if registered + if ( functab_attach_iterpolys[ obj->ObjectClass ] != NULL ) { + + D_BiasIterDepth( 1 ); + (*functab_attach_iterpolys[ obj->ObjectClass ])( obj, inorder ); + D_BiasIterDepth( 0 ); + } +} + + +// a single registered vertex set (one to many polys as a float list) --------- +// +struct attach_iterpolys_set_s { + + short apexid; // for clustering primitives to a single apex + short apexvtx; // vertex index that is apex (in a quad second must follow) + short apexcomp; // component to modulate with random value (usually z == 2) + short numprimvtxs; // number of vertices per primitive + + int numvtxs; // number of vertices in list + float* vtxs; // vertex list (set) +}; + + +// table of all particles to attach to a specific object class ---------------- +// +struct attach_iterpolys_tab_s { + + attach_iterpolys_set_s* sets; + short numsets; + short maxsets; +}; + + +// all registered iter polys for all object classes --------------------------- +// +PRIVATE +attach_iterpolys_tab_s attach_iterpolys_tab[ MAX_DISTINCT_OBJCLASSES ]; + + +// maximum number of shared apexes -------------------------------------------- +// +#define MAX_SHARED_APEXES 10 + + +// attach previously registered iter polygons --------------------------------- +// +PRIVATE +void AttachIterPolysRegistered( GenObject *obj, int inorder ) +{ + ASSERT( obj != NULL ); + ASSERT( OBJECT_TYPE_SHIP( obj ) ); + ASSERT( obj->ObjectClass < (dword)NumObjClasses ); + + // only immediately after the object is drawn + if ( !inorder ) { + return; + } + + dword objclass = obj->ObjectClass; + ShipObject *shippo = (ShipObject *) obj; + + attach_iterpolys_set_s *ipset = attach_iterpolys_tab[ objclass ].sets; + if ( ipset == NULL ) { + return; + } + + // setup transformation matrix + D_LoadIterMatrix( shippo->CurrentXmatrx ); + + IterRectangle3 _itprim; + IterPolygon3 *itprim = (IterPolygon3 *) &_itprim; + + itprim->flags = ITERFLAG_Z_DIV_XYZ | ITERFLAG_Z_TO_DEPTH; + itprim->itertype = iter_rgba | iter_additiveblend; + itprim->raststate = rast_nozwrite; + itprim->rastmask = rast_mask_zcompare; + + int rand8 = RAND() % 20; + float pbase = ( (float)GET_SPEED() / 2440.0 ); + + float apexrands[ MAX_SHARED_APEXES ]; + for ( int crand = 0; crand < MAX_SHARED_APEXES; crand++ ) { + apexrands[ crand ] = -pbase + ( RAND() % ( (int)pbase + 1 ) ) / 10.0; + } + + byte apex_r = 10 + rand8; + byte apex_g = 20 + rand8; + byte apex_b = 205 + rand8; + byte apex_a = 10 + rand8; + + byte base_r = 140 + rand8; + byte base_g = 140 + rand8; + byte base_b = 180 + rand8; + byte base_a = 96 + rand8; + + // change color of thrust polygons if afterburner active + CHECK_AFTERBURNER_COLOR(); + + // draw all iter polys from all vertex sets + for ( int acnt = attach_iterpolys_tab[ objclass ].numsets; acnt > 0; acnt--, ipset++ ) { + + ASSERT( ipset->apexvtx == 1 ); + ASSERT( ipset->apexcomp == 2 ); + + //TODO: + // use ipset->apexvtx and ipset->apexcomp. + + if ( ipset->numprimvtxs == 3 ) { + + float *vcpos = ipset->vtxs; + for ( int numvtxs = ipset->numvtxs; numvtxs > 0; numvtxs-=3, vcpos+=9 ) { + + itprim->Vtxs[ 0 ].X = FLOAT_TO_GEOMV( vcpos[ 0 ] ); + itprim->Vtxs[ 0 ].Y = FLOAT_TO_GEOMV( vcpos[ 1 ] ); + itprim->Vtxs[ 0 ].Z = FLOAT_TO_GEOMV( vcpos[ 2 ] ); + itprim->Vtxs[ 0 ].R = base_r; + itprim->Vtxs[ 0 ].G = base_g; + itprim->Vtxs[ 0 ].B = base_b; + itprim->Vtxs[ 0 ].A = base_a; + + itprim->Vtxs[ 1 ].X = FLOAT_TO_GEOMV( vcpos[ 3 ] ); + itprim->Vtxs[ 1 ].Y = FLOAT_TO_GEOMV( vcpos[ 4 ] ); + itprim->Vtxs[ 1 ].Z = FLOAT_TO_GEOMV( vcpos[ 5 ] + apexrands[ ipset->apexid ] ); + itprim->Vtxs[ 1 ].R = apex_r; + itprim->Vtxs[ 1 ].G = apex_g; + itprim->Vtxs[ 1 ].B = apex_b; + itprim->Vtxs[ 1 ].A = apex_a; + + itprim->Vtxs[ 2 ].X = FLOAT_TO_GEOMV( vcpos[ 6 ] ); + itprim->Vtxs[ 2 ].Y = FLOAT_TO_GEOMV( vcpos[ 7 ] ); + itprim->Vtxs[ 2 ].Z = FLOAT_TO_GEOMV( vcpos[ 8 ] ); + itprim->Vtxs[ 2 ].R = base_r; + itprim->Vtxs[ 2 ].G = base_g; + itprim->Vtxs[ 2 ].B = base_b; + itprim->Vtxs[ 2 ].A = base_a; + + // clip and draw polygon + D_DrawIterTriangle3( (IterTriangle3 *)itprim, 0x3f ); + } + + } else if ( ipset->numprimvtxs == 4 ) { + + float *vcpos = ipset->vtxs; + for ( int numvtxs = ipset->numvtxs; numvtxs > 0; numvtxs-=4, vcpos+=12 ) { + + itprim->Vtxs[ 0 ].X = FLOAT_TO_GEOMV( vcpos[ 0 ] ); + itprim->Vtxs[ 0 ].Y = FLOAT_TO_GEOMV( vcpos[ 1 ] ); + itprim->Vtxs[ 0 ].Z = FLOAT_TO_GEOMV( vcpos[ 2 ] ); + itprim->Vtxs[ 0 ].R = base_r; + itprim->Vtxs[ 0 ].G = base_g; + itprim->Vtxs[ 0 ].B = base_b; + itprim->Vtxs[ 0 ].A = base_a; + + itprim->Vtxs[ 1 ].X = FLOAT_TO_GEOMV( vcpos[ 3 ] ); + itprim->Vtxs[ 1 ].Y = FLOAT_TO_GEOMV( vcpos[ 4 ] ); + itprim->Vtxs[ 1 ].Z = FLOAT_TO_GEOMV( vcpos[ 5 ] + apexrands[ ipset->apexid ] ); + itprim->Vtxs[ 1 ].R = apex_r; + itprim->Vtxs[ 1 ].G = apex_g; + itprim->Vtxs[ 1 ].B = apex_b; + itprim->Vtxs[ 1 ].A = apex_a; + + itprim->Vtxs[ 2 ].X = FLOAT_TO_GEOMV( vcpos[ 6 ] ); + itprim->Vtxs[ 2 ].Y = FLOAT_TO_GEOMV( vcpos[ 7 ] ); + itprim->Vtxs[ 2 ].Z = FLOAT_TO_GEOMV( vcpos[ 8 ] + apexrands[ ipset->apexid ] ); + itprim->Vtxs[ 2 ].R = apex_r; + itprim->Vtxs[ 2 ].G = apex_g; + itprim->Vtxs[ 2 ].B = apex_b; + itprim->Vtxs[ 2 ].A = apex_a; + + itprim->Vtxs[ 3 ].X = FLOAT_TO_GEOMV( vcpos[ 9 ] ); + itprim->Vtxs[ 3 ].Y = FLOAT_TO_GEOMV( vcpos[ 10 ] ); + itprim->Vtxs[ 3 ].Z = FLOAT_TO_GEOMV( vcpos[ 11 ] ); + itprim->Vtxs[ 3 ].R = base_r; + itprim->Vtxs[ 3 ].G = base_g; + itprim->Vtxs[ 3 ].B = base_b; + itprim->Vtxs[ 3 ].A = base_a; + + // clip and draw polygon + D_DrawIterRectangle3( (IterRectangle3 *)itprim, 0x3f ); + } + + } else if ( ipset->numprimvtxs == 5 ) { + + //TODO: + ASSERT( 0 ); + } + } +} + + +// reset registered iter polys for specified class ---------------------------- +// +void OBJ_ResetRegisteredClassIterPolys( dword objclass ) +{ + ASSERT( objclass < (dword)NumObjClasses ); + + functab_attach_iterpolys[ objclass ] = NULL; + + if ( attach_iterpolys_tab[ objclass ].sets != NULL ) { + + // free all allocated vertex lists (corresponding to sets) + for ( int cset = 0; cset < attach_iterpolys_tab[ objclass ].numsets; cset++ ) { + ASSERT( attach_iterpolys_tab[ objclass ].sets[ cset ].vtxs != NULL ); + FREEMEM( attach_iterpolys_tab[ objclass ].sets[ cset ].vtxs ); + } + + // free vertex sets + FREEMEM( attach_iterpolys_tab[ objclass ].sets ); + attach_iterpolys_tab[ objclass ].sets = NULL; + } +} + + +// maximum number of vertex sets that can be registered per class ------------- +// +#define MAX_ATTACH_VERTEX_SETS 100 + + +// register iter polys to attach to class (one call register a vertex set) ---- +// +int OBJ_RegisterClassIterPolys( dword objclass, int apexid, int apexvtx, int apexcomp, int numprimvtxs, int numvtxs, float *vtxlist ) +{ + ASSERT( objclass < (dword)NumObjClasses ); + ASSERT( vtxlist != NULL ); + + // register general callback for this class if not already done + if ( functab_attach_iterpolys[ objclass ] == NULL ) { + functab_attach_iterpolys[ objclass ] = AttachIterPolysRegistered; + } + + // create new table of iter polys (vertex set) to attach if not yet there + if ( attach_iterpolys_tab[ objclass ].sets == NULL ) { + attach_iterpolys_tab[ objclass ].sets = (attach_iterpolys_set_s *) + ALLOCMEM( MAX_ATTACH_VERTEX_SETS * sizeof( attach_iterpolys_set_s ) ); + if ( attach_iterpolys_tab[ objclass ].sets == NULL ) + OUTOFMEM( "no mem for iter poly vertex sets." ); + attach_iterpolys_tab[ objclass ].numsets = 0; + attach_iterpolys_tab[ objclass ].maxsets = MAX_ATTACH_VERTEX_SETS; + } + + // guard against overflow + if ( attach_iterpolys_tab[ objclass ].numsets == attach_iterpolys_tab[ objclass ].maxsets ) { + return FALSE; + } + + // alloc vertex list in the exact size needed (source may be larger) + float *_vtxlist = (float *) ALLOCMEM( numvtxs * 3 * sizeof( float ) ); + if ( _vtxlist == NULL ) + OUTOFMEM( 0 ); + memcpy( _vtxlist, vtxlist, numvtxs * 3 * sizeof( float ) ); + vtxlist = _vtxlist; + + // register this vertex set + attach_iterpolys_set_s *ipset = &attach_iterpolys_tab[ objclass ].sets[ attach_iterpolys_tab[ objclass ].numsets ]; + + ipset->apexid = apexid; + ipset->apexvtx = apexvtx; + ipset->apexcomp = apexcomp; + ipset->numprimvtxs = numprimvtxs; + ipset->numvtxs = numvtxs; + ipset->vtxs = vtxlist; + + attach_iterpolys_tab[ objclass ].numsets++; + + return TRUE; +} + + +// register attachment function ----------------------------------------------- +// +PRIVATE +int OBJ_RegisterAttachIterPolys( const char *classname, attach_iterpolys_fpt atfunc ) +{ + ASSERT( classname != NULL ); + + // try to resolve name to id + dword classid = OBJ_FetchObjectClassId( classname ); + if ( classid == CLASS_ID_INVALID ) { + return FALSE; + } + + // double registration not allowed + if ( functab_attach_iterpolys[ classid ] != NULL ) { + return FALSE; + } + + // set callback + functab_attach_iterpolys[ classid ] = atfunc; + + return TRUE; +} + + +// register attachment functions for all accessible classes ------------------- +// +PRIVATE +void RegisterAttachIterPolysCallback( int numparams, int *params ) +{ + //NOTE: + // must be idempotent. + + // ships + OBJ_RegisterAttachIterPolys( + OBJCLASSNAME_SHIP_FIREBIRD, AttachIterPolysFirebird ); + + OBJ_RegisterAttachIterPolys( + OBJCLASSNAME_SHIP_BLUESPIRE, AttachIterPolysBluespire ); + + OBJ_RegisterAttachIterPolys( + OBJCLASSNAME_SHIP_CORMORAN, AttachIterPolysCormoran ); + + OBJ_RegisterAttachIterPolys( + OBJCLASSNAME_SHIP_STINGRAY, AttachIterPolysStingray ); + + OBJ_RegisterAttachIterPolys( + OBJCLASSNAME_SHIP_CLAYMORE, AttachIterPolysClaymore ); + + OBJ_RegisterAttachIterPolys( + OBJCLASSNAME_SHIP_HURRICANE, AttachIterPolysHurricane ); +} + + +// module registration function ----------------------------------------------- +// +REGISTER_MODULE( OBJ_ITER ) +{ + // redundant + for ( int cid = 0; cid < MAX_DISTINCT_OBJCLASSES; cid++ ) { + functab_attach_iterpolys[ cid ] = NULL; + } + + // register on creg + OBJ_RegisterClassRegistration( RegisterAttachIterPolysCallback ); +} + + + -- cgit v1.2.3