Un-ignored: the dev drive is the ground truth the restoration and emulator work constantly reference (DPL3/LIBDPL + VRENDER i860 renderer source, BT/RP live+dev game trees, VGL_LABS pod boot, scene/audio content). Kept in-repo for the pod-owner community. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
916 lines
22 KiB
C++
916 lines
22 KiB
C++
/*{{{ about sfx.c*/
|
|
/* ***************************************************************
|
|
|
|
Create, initialize and time-step explosions and other paz fx's
|
|
|
|
Organizing these is going to be fun.
|
|
|
|
Ideally, the PAZ effects should look just like instances in the display
|
|
list, but should reference effects rather than objects. In fact, they
|
|
should reference objects whos geometry is warped every frame. Then
|
|
everything else works, they can be enabled and disabled, and can be
|
|
inserted into right and left eye displaylists just fine. The random
|
|
number generator MUST be consistent between the eyes, or all hell will
|
|
break loose. For efficiency needs a prime-number sized random number
|
|
table, primed from a random function. So lets put a random table
|
|
into static space, and index off it.
|
|
|
|
*/
|
|
|
|
/*}}} */
|
|
/*{{{ includes / externs*/
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <math.h>
|
|
#include "macros.h"
|
|
#include "pazpl5.h"
|
|
#include "pazstore.h"
|
|
#include "matrix.h"
|
|
#include "names.h"
|
|
#include "i860sem.h"
|
|
#include "viz.h"
|
|
#include "material.h"
|
|
|
|
extern concurrency_control *shared_cntl;
|
|
extern int scene_resolved;
|
|
/*}}} */
|
|
|
|
/*{{{ reproducible random number support*/
|
|
/* as always, this is CASIO calculator output */
|
|
|
|
static float sfx_random_numbers[67] = { 0.990f, 0.196f, 0.030f, 0.452f,
|
|
0.165f, 0.663f, 0.737f, 0.774f,
|
|
0.996f, 0.269f, 0.676f, 0.786f,
|
|
0.123f, 0.474f, 0.755f, 0.919f,
|
|
0.873f, 0.603f, 0.628f, 0.045f,
|
|
0.089f, 0.509f, 0.413f, 0.416f,
|
|
0.304f, 0.011f, 0.083f, 0.110f,
|
|
0.177f, 0.602f, 0.810f, 0.181f,
|
|
0.723f, 0.394f, 0.035f, 0.873f,
|
|
0.678f, 0.331f, 0.407f, 0.499f,
|
|
0.132f, 0.210f, 0.081f, 0.550f,
|
|
0.344f, 0.894f, 0.469f, 0.307f,
|
|
0.641f, 0.936f, 0.779f, 0.833f,
|
|
0.373f, 0.915f, 0.972f, 0.887f,
|
|
0.019f, 0.613f, 0.540f, 0.898f,
|
|
0.755f, 0.689f, 0.076f, 0.173f,
|
|
0.870f, 0.825f, 0.364f };
|
|
|
|
|
|
static int sfx_random_ix = 0;
|
|
static int sfx_random_base = 0;
|
|
|
|
static float float_0to1 ()
|
|
{
|
|
sfx_random_ix++;
|
|
|
|
if (sfx_random_ix >= 67)
|
|
sfx_random_ix=0;
|
|
|
|
return sfx_random_numbers[sfx_random_ix];
|
|
}
|
|
/*}}} */
|
|
|
|
#define PAZ_X X
|
|
#define PAZ_Y Y
|
|
#define PAZ_Z Z
|
|
|
|
/*{{{ explosion structure*/
|
|
#define FRAG_TRIANGLES 24
|
|
#define FRAG_SPHERES 32
|
|
|
|
#define bang_type_poly 0
|
|
#define bang_type_sphere 1
|
|
|
|
typedef struct s_bang {
|
|
int type;
|
|
INSTANCE *inst;
|
|
POINT velocity [ FRAG_SPHERES];
|
|
POINT translate [ FRAG_SPHERES];
|
|
int below_ground[ FRAG_SPHERES];
|
|
float blast_radius;
|
|
float switch_off;
|
|
int n_below;
|
|
int cool;
|
|
float sphere_rad;
|
|
float dt;
|
|
int frame_number;
|
|
} big_bang;
|
|
/*}}} */
|
|
|
|
#define MAX_PAZ_EXPLOSIONS 8
|
|
#define MAX_PAZ_FIRES 8
|
|
|
|
big_bang *paz_explosions[MAX_PAZ_EXPLOSIONS];
|
|
|
|
int paz_explosions_active=0;
|
|
|
|
static int first_bang=1;
|
|
static int first_mtl =1;
|
|
|
|
/*{{{ static void makeBangMtls(void)*/
|
|
static void makeBangMtls(void)
|
|
{
|
|
MATERIAL *mtl;
|
|
if (first_mtl==0)
|
|
return;
|
|
|
|
/* printf ("makeBangMtls\n" ); */
|
|
first_mtl=0;
|
|
|
|
mtl=create_material();
|
|
add_material(mtl);
|
|
|
|
strcpy ( mtl->material_name, "bang_50_perc" );
|
|
mtl->kd[0]=1.0f;
|
|
mtl->kd[1]=0.8f;
|
|
mtl->kd[2]=0.5f;
|
|
mtl->opacity=0.51f;
|
|
|
|
mtl=create_material();
|
|
add_material(mtl);
|
|
|
|
strcpy ( mtl->material_name, "bang_frag" );
|
|
|
|
mtl->kd[0]=0.99f;
|
|
mtl->kd[1]=0.99f;
|
|
mtl->kd[2]=0.99f;
|
|
|
|
mtl=create_material();
|
|
add_material(mtl);
|
|
|
|
strcpy ( mtl->material_name, "bang_gore" );
|
|
|
|
mtl->kd[0]=0.99f;
|
|
mtl->kd[1]=0.1f;
|
|
mtl->kd[2]=0.1f;
|
|
/* printf ("made bangMtls\n" ); */
|
|
}
|
|
/*}}} */
|
|
|
|
/*{{{ static VERTEX *vertex_block ( int verts, VSTRIP *v )*/
|
|
static VERTEX *vertex_block ( int verts, VSTRIP *v )
|
|
{
|
|
VERTEX *solid, *vert;
|
|
int i;
|
|
|
|
solid=_NewVertices(verts);
|
|
|
|
vert=solid;
|
|
|
|
for (i=0; i<verts; i++ ) {
|
|
v->tail=vert;
|
|
vert->next=vert+1;
|
|
vert=vert->next;
|
|
}
|
|
|
|
v->tail->next=NULL;
|
|
v->head=solid;
|
|
|
|
v->vertex_count=verts;
|
|
|
|
return solid;
|
|
|
|
}
|
|
/*}}} */
|
|
/*{{{ static void initBang ( big_bang *bang, int bang_type,*/
|
|
|
|
static void initBang ( big_bang *bang,
|
|
int bang_type,
|
|
float blast_radius,
|
|
float frag_size,
|
|
float frag_velocity,
|
|
float vertical_bias,
|
|
float switch_off,
|
|
float cook_r, float cook_g, float cook_b,
|
|
float variance,
|
|
int cool )
|
|
{
|
|
int i, j;
|
|
|
|
OBJECT *obj;
|
|
LOD *lod;
|
|
PATCH *p;
|
|
VSTRIP *v;
|
|
VERTEX *vert;
|
|
|
|
int limit=FRAG_TRIANGLES;
|
|
|
|
obj = nameToAddress ( bang->inst->obj, viz_createObject );
|
|
lod = obj->head;
|
|
p = lod->head;
|
|
v = p->head;
|
|
vert = v->head;
|
|
|
|
sfx_random_ix=sfx_random_base;
|
|
sfx_random_base++;
|
|
|
|
cook_r*=255.9f;
|
|
cook_g*=255.9f;
|
|
cook_b*=255.9f;
|
|
|
|
if (sfx_random_base >= 67)
|
|
sfx_random_base=0;
|
|
|
|
bang->dt=0.15f;
|
|
bang->cool=cool;
|
|
bang->type=bang_type;
|
|
bang->inst->enable=0;
|
|
bang->frame_number=0;
|
|
bang->switch_off = switch_off;
|
|
bang->blast_radius=blast_radius;
|
|
|
|
bang->n_below=0;
|
|
bang->sphere_rad=0.35f;
|
|
|
|
if (bang->type == bang_type_poly)
|
|
limit=FRAG_TRIANGLES;
|
|
else
|
|
limit=FRAG_SPHERES;
|
|
|
|
frag_velocity*=39.0f;
|
|
|
|
for (i=0; i<limit; i++ ) {
|
|
float rest, t;
|
|
|
|
bang->below_ground[i]=0;
|
|
|
|
bang->velocity[i][PAZ_X]=frag_velocity * (float_0to1() - 0.5f);
|
|
bang->velocity[i][PAZ_Y]=frag_velocity * ((float_0to1() - 0.5f) + vertical_bias);
|
|
bang->velocity[i][PAZ_Z]=frag_velocity * (float_0to1() - 0.5f);
|
|
|
|
vert->position[0]=frag_size * (float_0to1() - 0.5f);
|
|
vert->position[1]=frag_size * (float_0to1() - 0.3f);
|
|
vert->position[2]=frag_size * (float_0to1() - 0.5f);
|
|
vert->position[3]=0;
|
|
|
|
/*{{{ */
|
|
rest =1.0f - (variance * float_0to1());
|
|
t=rest*cook_r;
|
|
if (t>255.9f) t=255.9f;
|
|
/*}}} */
|
|
vert->normcol[0]=t;
|
|
/*{{{ */
|
|
rest =1.0f - (variance * float_0to1());
|
|
t=rest*cook_g;
|
|
if (t>255.9f) t=255.9f;
|
|
/*}}} */
|
|
vert->normcol[1]=t;
|
|
/*{{{ */
|
|
rest =1.0f - (variance * float_0to1());
|
|
t=rest*cook_b;
|
|
if (t>255.9f) t=255.9f;
|
|
/*}}} */
|
|
vert->normcol[2]=t;
|
|
|
|
if (bang->type == bang_type_poly) {
|
|
vert++;
|
|
vert->position[0]=frag_size * (float_0to1() - 0.5f);
|
|
vert->position[1]=frag_size * (float_0to1() - 0.3f);
|
|
vert->position[2]=frag_size * (float_0to1() - 0.5f);
|
|
vert->position[3]=0;
|
|
|
|
/*{{{ */
|
|
rest =1.0f - (variance * float_0to1());
|
|
t=rest*cook_r;
|
|
if (t>255.9f) t=255.9f;
|
|
/*}}} */
|
|
vert->normcol[0]=t;
|
|
/*{{{ */
|
|
rest =1.0f - (variance * float_0to1());
|
|
t=rest*cook_g;
|
|
if (t>255.9f) t=255.9f;
|
|
/*}}} */
|
|
vert->normcol[1]=t;
|
|
/*{{{ */
|
|
rest =1.0f - (variance * float_0to1());
|
|
t=rest*cook_b;
|
|
if (t>255.9f) t=255.9f;
|
|
/*}}} */
|
|
vert->normcol[2]=t;
|
|
vert++;
|
|
|
|
vert->position[0]=frag_size * (float_0to1() - 0.5f);
|
|
vert->position[1]=frag_size * (float_0to1() - 0.3f);
|
|
vert->position[2]=frag_size * (float_0to1() - 0.5f);
|
|
vert->position[3]=0;
|
|
|
|
/*{{{ */
|
|
rest =1.0f - (variance * float_0to1());
|
|
t=rest*cook_r;
|
|
if (t>255.9f) t=255.9f;
|
|
/*}}} */
|
|
vert->normcol[0]=t;
|
|
/*{{{ */
|
|
rest =1.0f - (variance * float_0to1());
|
|
t=rest*cook_g;
|
|
if (t>255.9f) t=255.9f;
|
|
/*}}} */
|
|
vert->normcol[1]=t;
|
|
/*{{{ */
|
|
rest =1.0f - (variance * float_0to1());
|
|
t=rest*cook_b;
|
|
if (t>255.9f) t=255.9f;
|
|
/*}}} */
|
|
vert->normcol[2]=t;
|
|
vert++;
|
|
}
|
|
else {
|
|
vert->position[3]=bang->sphere_rad;
|
|
vert++;
|
|
}
|
|
}
|
|
|
|
bound_patch ( p );
|
|
compute_pmesh_plane_eqns ( p, 0 );
|
|
|
|
reboundLOD ( lod );
|
|
reboundObject ( obj );
|
|
|
|
}
|
|
/*}}} */
|
|
/*{{{ static big_bang *createBang ( int type, float qual )*/
|
|
static big_bang *createBang ( int type, float qual )
|
|
{
|
|
surface s;
|
|
int i, strip_shade;
|
|
float *fp;
|
|
big_bang *bang;
|
|
OBJECT *obj;
|
|
LOD *lod;
|
|
PATCH *p;
|
|
PATCHISSIMO *pi;
|
|
VSTRIP *v;
|
|
VERTEX *vert;
|
|
VERTEX *tess;
|
|
OBJLIST *sg=&sceneGeometry;
|
|
|
|
/*{{{ initialize bang structure*/
|
|
makeBangMtls();
|
|
|
|
bang=(big_bang *) malloc(sizeof(big_bang));
|
|
|
|
bang->type=type;
|
|
|
|
bang->inst=PAZcreateInstance();
|
|
|
|
bang->inst->obj=NULL;
|
|
bang->inst->enable=0;
|
|
|
|
s.COOKED=1;
|
|
|
|
/*}}} */
|
|
|
|
/*{{{ start up the PAZ stuff, object and lod*/
|
|
_InitObject(obj=_NewObject());
|
|
_InitLOD(lod=_NewLOD());
|
|
|
|
lod->vertex_count=0;
|
|
|
|
lod->switch_in =0.0f;
|
|
lod->switch_out=1024.0f * 1024.0f;
|
|
|
|
bang->inst->obj=(OBJECT *) newName ( obj, viz_createObject );
|
|
/*}}} */
|
|
|
|
/*{{{ build frag geometry*/
|
|
/* printf ("createBang making frag geometry\n" ); */
|
|
if (type == bang_type_poly) {
|
|
/*{{{ pmesh*/
|
|
|
|
/*{{{ build pmesh header*/
|
|
/* printf ("createBang went InitPatch\n" ); */
|
|
_InitPatch((PATCH *) (pi=_NewPatchissimo()));
|
|
|
|
pi->sem=nextSem();
|
|
InitSem (pi->sem);
|
|
|
|
p=(PATCH *) pi;
|
|
|
|
strcpy ( p->fmaterial_name, "bang_frag" );
|
|
strcpy ( p->bmaterial_name, "bang_frag" );
|
|
|
|
p->patch_type = patch_type_pmesh;
|
|
|
|
strip_shade=strip_shade_coloured;
|
|
/*}}} */
|
|
|
|
/* printf ("createBang building vertices\n" ); */
|
|
/*{{{ build vertices*/
|
|
_InitVstrip(v=_NewVstrip());
|
|
vertex_block ( FRAG_TRIANGLES*3, v );
|
|
tess=v->head;
|
|
vert=tess;
|
|
|
|
v->strip_shade=strip_shade;
|
|
add_item(p, v);
|
|
|
|
p->vertex_count=v->vertex_count;
|
|
|
|
if (v->vertex_count > shared_cntl->length_longest_verts)
|
|
shared_cntl->length_longest_verts=v->vertex_count;
|
|
/*}}} */
|
|
|
|
/* printf ("createBang building connections\n" ); */
|
|
/*{{{ build connexions*/
|
|
_InitVstrip(v=_NewVstrip());
|
|
v->strip_shade=strip_shade;
|
|
vertex_block ( FRAG_TRIANGLES, v );
|
|
vert=v->head;
|
|
|
|
for ( i=0; i<FRAG_TRIANGLES; i++ ) {
|
|
int three_i = 3*i;
|
|
int *ipos = (int *) &(vert->position[0]);
|
|
|
|
ipos[0]=(int) (&tess[three_i]);
|
|
ipos[1]=(int) (&tess[three_i+1]);
|
|
ipos[2]=(int) (&tess[three_i+2]);
|
|
|
|
vert++;
|
|
}
|
|
add_item(p, v);
|
|
|
|
if (v->vertex_count > shared_cntl->length_longest_tris)
|
|
shared_cntl->length_longest_tris=v->vertex_count;
|
|
|
|
/*}}} */
|
|
|
|
|
|
/*}}} */
|
|
}
|
|
else {
|
|
#if 0
|
|
/*{{{ sphere mesh*/
|
|
VSTRIP *next;
|
|
VSTRIP *tess, *connect;
|
|
VERTEX *vert, *conn_list;
|
|
int num, i, first_strip=1, mesh_verts, mesh_tris;
|
|
|
|
/*{{{ read smesh*/
|
|
|
|
_InitPatch((PATCH *) (pi=_NewPatchissimo()));
|
|
|
|
pi->sem=nextSem();
|
|
InitSem (pi->sem);
|
|
|
|
p=(PATCH *) pi;
|
|
|
|
memcpy ( &patch_surf, (char *) &data[2], sizeof (surface) );
|
|
set_surface ( p, &patch_surf );
|
|
|
|
p->patch_type = patch_type_smesh;
|
|
|
|
strip_shade=0;
|
|
|
|
strip_shade|=strip_shade_smooth;
|
|
|
|
/* expect just 1 strip, and do magic with it */
|
|
|
|
data=(int *) gets_fn(0,6,0);
|
|
if (data[0] != viz_openBinStrip) {
|
|
mexico_68 ("binRead DIDNT get strip\n" );
|
|
}
|
|
else {
|
|
/*{{{ read each strip*/
|
|
int i, stype=data[1], verts=data[2], nfloats=data[3], accum=0;
|
|
float *vptr;
|
|
|
|
points+=verts;
|
|
triangles+=verts-2;
|
|
|
|
_InitVstrip(v=_NewVstrip());
|
|
|
|
/*{{{ malloc, init and listize new store*/
|
|
|
|
solid=_NewVertices(verts);
|
|
|
|
if (solid==NULL)
|
|
mexico_68 ("failed to malloc %d vertices (points=%d triangles=%d)\n",
|
|
verts, points, triangles, NULL );
|
|
|
|
vert=solid;
|
|
|
|
for (i=0; i<verts; i++ ) {
|
|
v->tail=vert;
|
|
vert->next=vert+1;
|
|
vert=vert->next;
|
|
}
|
|
|
|
v->tail->next=NULL;
|
|
v->head=solid;
|
|
|
|
v->vertex_count=verts;
|
|
v->strip_shade=strip_shade;
|
|
v->strip_type=stype;
|
|
v->normals=patch_surf.NORMALS;
|
|
|
|
vert=v->head;
|
|
/*}}} */
|
|
|
|
data=(int *) gets_fn(0,0,0);
|
|
|
|
while (data[0] == viz_binGeometry) {
|
|
/*{{{ put these items into strip*/
|
|
int j;
|
|
/* extract vertices from structure */
|
|
/* copy each of verts into new structure */
|
|
|
|
accum+=data[1];
|
|
|
|
vptr=(float *) &data[2];
|
|
|
|
for (j=0; j<data[1]; j++ ) {
|
|
if (vert==NULL)
|
|
mexico_68 ( "DEEP bogosity - too many vertices\n" );
|
|
|
|
vert->position[0]=*vptr++;
|
|
vert->position[1]=*vptr++;
|
|
vert->position[2]=*vptr++;
|
|
vert->position[3]=*vptr++;
|
|
|
|
vert=vert->next;
|
|
}
|
|
/*}}} */
|
|
dN_reply();
|
|
data=(int *) gets_fn(0,0,0);
|
|
}
|
|
/*}}} */
|
|
add_item(p, v);
|
|
p->vertex_count+=v->vertex_count;
|
|
first_strip=0;
|
|
}
|
|
/*}}} */
|
|
|
|
/*{{{ now do smesh magic rearrangement*/
|
|
tess=p->head;
|
|
|
|
mesh_verts=tess->vertex_count;
|
|
|
|
if (mesh_verts > shared_cntl->length_longest_verts)
|
|
shared_cntl->length_longest_verts=mesh_verts;
|
|
|
|
tess->next=NULL;
|
|
|
|
p->head=tess;
|
|
p->tail=tess;
|
|
|
|
/*}}} */
|
|
|
|
/*}}} */
|
|
initBang ( bang, bang->type, qual, 20.0f, 12.0f, 3.0f, -10.0f );
|
|
bound_spatch ( p );
|
|
#endif
|
|
}
|
|
|
|
lod->vertex_count+=p->vertex_count;
|
|
|
|
add_item ( lod, p );
|
|
/*}}} */
|
|
|
|
add_item (obj, lod);
|
|
|
|
reconnectLODs ( obj );
|
|
|
|
add_item ( sg, obj );
|
|
|
|
initBang ( bang, bang_type_poly, 20.0f, 8.0f, 2.5f, -8.0f,
|
|
0.2f, 0.2, 0.2, 0.2, 0.3, 0 );
|
|
|
|
scene_resolved=0;
|
|
|
|
return bang;
|
|
}
|
|
/*}}} */
|
|
/*{{{ static int step_bang ( big_bang *bang )*/
|
|
static int step_bang ( big_bang *bang )
|
|
{
|
|
int i, ret;
|
|
float g=9.8f;
|
|
int xforms, stop_count;
|
|
OBJECT *obj;
|
|
LOD *lod;
|
|
PATCH *p;
|
|
VSTRIP *v;
|
|
VERTEX *vert;
|
|
|
|
float rcool_factor=0.985f;
|
|
float gcool_factor=0.96f;
|
|
float bcool_factor=0.935f;
|
|
|
|
int tweak_colour=bang->cool;
|
|
|
|
/* printf ("step_bang 0x%x\n", bang ); */
|
|
|
|
if (bang->inst==NULL) {
|
|
return;
|
|
}
|
|
else {
|
|
obj=(OBJECT *) nameToAddress(bang->inst->obj, viz_createObject );
|
|
if (obj==NULL) return;
|
|
}
|
|
|
|
lod = obj->head;
|
|
p = lod->head;
|
|
v = p->head;
|
|
vert = v->head;
|
|
|
|
/* right - v is now the vertex list for the frags */
|
|
|
|
if (bang->type == bang_type_poly) {
|
|
stop_count=FRAG_TRIANGLES;
|
|
xforms =FRAG_TRIANGLES;
|
|
}
|
|
else {
|
|
stop_count=FRAG_SPHERES;
|
|
xforms =FRAG_SPHERES;
|
|
/* bang->sphere_rad*=0.982; */
|
|
}
|
|
|
|
for (i=0; i<xforms; i++) {
|
|
/*{{{ do a frag (triangle or sphere)*/
|
|
float dx, dy, dz;
|
|
|
|
bang->velocity[i][PAZ_Y]-=bang->dt*g;
|
|
|
|
dx=bang->translate[i][PAZ_X]=bang->dt*bang->velocity[i][PAZ_X];
|
|
dy=bang->translate[i][PAZ_Y]=bang->dt*bang->velocity[i][PAZ_Y];
|
|
dz=bang->translate[i][PAZ_Z]=bang->dt*bang->velocity[i][PAZ_Z];
|
|
|
|
vert->position[0]+=dx;
|
|
vert->position[1]+=dy;
|
|
vert->position[2]+=dz;
|
|
|
|
if (tweak_colour) {
|
|
vert->normcol[0]*=rcool_factor;
|
|
vert->normcol[1]*=gcool_factor;
|
|
vert->normcol[2]*=bcool_factor;
|
|
}
|
|
|
|
if (vert->position[1] < bang->switch_off) {
|
|
if (bang->below_ground[i] == 0) {
|
|
bang->below_ground[i]=1;
|
|
bang->n_below++;
|
|
}
|
|
}
|
|
|
|
if (bang->type==bang_type_poly) {
|
|
float r=vert->normcol[0],
|
|
g=vert->normcol[1],
|
|
b=vert->normcol[2];
|
|
vert++;
|
|
|
|
vert->position[0]+=dx;
|
|
vert->position[1]+=dy;
|
|
vert->position[2]+=dz;
|
|
vert->normcol[0]=r;
|
|
vert->normcol[1]=g;
|
|
vert->normcol[2]=b;
|
|
vert++;
|
|
|
|
vert->position[0]+=dx;
|
|
vert->position[1]+=dy;
|
|
vert->position[2]+=dz;
|
|
vert->normcol[0]=r;
|
|
vert->normcol[1]=g;
|
|
vert->normcol[2]=b;
|
|
}
|
|
else {
|
|
vert->position[3]=bang->sphere_rad;
|
|
}
|
|
/*}}} */
|
|
vert++;
|
|
}
|
|
|
|
if (bang->type == bang_type_poly)
|
|
bound_patch ( p );
|
|
else
|
|
bound_spatch ( p );
|
|
|
|
bang->frame_number++;
|
|
bang->dt=0.15; /* 1/8th sec */
|
|
|
|
reboundLOD ( lod );
|
|
reboundObject ( obj );
|
|
|
|
if (bang->n_below == stop_count) {
|
|
bang->inst->enable=0;
|
|
}
|
|
else {
|
|
ret=1;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
/*}}} */
|
|
|
|
/*{{{ int sfx_init()*/
|
|
int sfx_inited=0;
|
|
|
|
int sfx_init ()
|
|
{
|
|
int i;
|
|
|
|
if (sfx_inited)
|
|
return;
|
|
|
|
sfx_inited=1;
|
|
|
|
for (i=0; i<MAX_PAZ_EXPLOSIONS; i++ ) {
|
|
int j;
|
|
INSTANCE *inst;
|
|
|
|
paz_explosions[i]=createBang(bang_type_poly, 0.99f);
|
|
|
|
initBang ( paz_explosions[i],
|
|
bang_type_poly,
|
|
20.0f + 3.0f*float_0to1(),
|
|
10.0f + 3.0f*float_0to1(),
|
|
1.0f + 3.0f*float_0to1(),
|
|
0.4f,
|
|
-3.0f - 3.0f*float_0to1(),
|
|
0.2f, 0.3f, 0.2f, 0.3, 0 );
|
|
|
|
inst=paz_explosions[i]->inst;
|
|
|
|
_idmatrix ( inst->f );
|
|
_translate ( inst->f,
|
|
(float_0to1() - 0.5f) * 30*(i&3),
|
|
30.0f,
|
|
(float_0to1() + 0.5f) * 30*(i>>2),
|
|
1 );
|
|
|
|
_invert ( inst->b, inst->f );
|
|
}
|
|
}
|
|
/*}}} */
|
|
|
|
/*{{{ void PAZsfx ( int code, float qual, MATRIX m )*/
|
|
static int active_fx=0;
|
|
|
|
void PAZsfx ( int code, float qual, MATRIX m )
|
|
{
|
|
big_bang *bang;
|
|
|
|
if (sfx_inited == 0)
|
|
return;
|
|
|
|
bang=paz_explosions[active_fx];
|
|
active_fx++;
|
|
|
|
if (active_fx == MAX_PAZ_EXPLOSIONS)
|
|
active_fx=0;
|
|
|
|
if (code == 0) {
|
|
/*{{{ small explosion, small frags*/
|
|
initBang ( bang, bang->type,
|
|
18.0f, 13.0f, 1.2f,
|
|
0.2f,
|
|
-6.0f-m[3][1],
|
|
0.19f, 0.2f, 0.2f, 0.3, 0 );
|
|
|
|
bang->inst->enable=1;
|
|
memcpy ( bang->inst->f, m, sizeof(MATRIX));
|
|
_invert ( bang->inst->b, bang->inst->f );
|
|
/*}}} */
|
|
}
|
|
else if (code == 1) {
|
|
/*{{{ medium explosion, medium frags*/
|
|
MATRIX tmp;
|
|
|
|
/* explosion 0 - hi-velocity, not much upward bias */
|
|
|
|
memcpy ( tmp, m, sizeof(MATRIX));
|
|
|
|
initBang ( bang, bang->type,
|
|
42.0f, 41.0f, 3.5f,
|
|
0.31f,
|
|
-36.0f-m[3][1],
|
|
0.99f, 0.99f, 0.91f, 0.2, 1 );
|
|
|
|
bang->inst->enable=1;
|
|
|
|
_rotY ( tmp, 56.0f, 0 );
|
|
|
|
_translate ( tmp,
|
|
0,
|
|
30.0f + (float_0to1() * 30.0f),
|
|
0, 0 );
|
|
|
|
/* explosion 1 - lower-velocity, more upward bias */
|
|
|
|
memcpy ( bang->inst->f, tmp, sizeof(MATRIX));
|
|
_invert ( bang->inst->b, bang->inst->f );
|
|
|
|
bang=paz_explosions[active_fx];
|
|
|
|
active_fx++;
|
|
|
|
if (active_fx == MAX_PAZ_EXPLOSIONS)
|
|
active_fx=0;
|
|
|
|
memcpy ( tmp, m, sizeof(MATRIX));
|
|
|
|
initBang ( bang, bang->type,
|
|
42.0f, 41.0f, 2.8f,
|
|
0.75f,
|
|
-36.0f-m[3][1],
|
|
0.91f, 0.91f, 0.91f, 0.2, 1 );
|
|
|
|
bang->inst->enable=1;
|
|
|
|
memcpy ( bang->inst->f, tmp, sizeof(MATRIX));
|
|
_invert ( bang->inst->b, bang->inst->f );
|
|
|
|
bang=paz_explosions[active_fx];
|
|
|
|
active_fx++;
|
|
|
|
if (active_fx == MAX_PAZ_EXPLOSIONS)
|
|
active_fx=0;
|
|
|
|
/*}}} */
|
|
}
|
|
else if (code == 2) {
|
|
/*{{{ small explosion, red frags*/
|
|
initBang ( bang, bang->type,
|
|
18.0f, 14.0f, 1.3f,
|
|
0.3f,
|
|
-6.0f-m[3][1],
|
|
0.99f, 0.2f, 0.2f, 0.3, 0 );
|
|
|
|
bang->inst->enable=1;
|
|
memcpy ( bang->inst->f, m, sizeof(MATRIX));
|
|
_invert ( bang->inst->b, bang->inst->f );
|
|
/*}}} */
|
|
}
|
|
else if (code == 3) {
|
|
/*{{{ big explosion(s), big frags*/
|
|
int i;
|
|
MATRIX tmp;
|
|
|
|
for (i=0; i<4; i++ ) {
|
|
memcpy ( tmp, m, sizeof(MATRIX));
|
|
|
|
initBang ( bang,
|
|
bang->type,
|
|
80.0f + 10.0f*float_0to1(),
|
|
45.0f + 15.0f*float_0to1(),
|
|
4.3f + 1.6f*float_0to1(),
|
|
0.25f + 0.2f*float_0to1(),
|
|
-36.0f-m[3][1],
|
|
0.99, 0.8, 0.85, 0.2, 1 );
|
|
|
|
bang->inst->enable=1;
|
|
|
|
_rotY ( tmp, (float) i * 56.0f, 0 );
|
|
|
|
_translate ( tmp,
|
|
60.0f*(float_0to1() - 0.5f),
|
|
float_0to1() * 30.0f,
|
|
60.0f*(float_0to1() - 0.5f), 0 );
|
|
|
|
|
|
memcpy ( bang->inst->f, tmp, sizeof(MATRIX));
|
|
_invert ( bang->inst->b, bang->inst->f );
|
|
|
|
bang=paz_explosions[active_fx];
|
|
|
|
active_fx++;
|
|
|
|
if (active_fx == MAX_PAZ_EXPLOSIONS)
|
|
active_fx=0;
|
|
|
|
}
|
|
/*}}} */
|
|
}
|
|
else {
|
|
printf ("Unknown sfx type\n" );
|
|
}
|
|
}
|
|
/*}}} */
|
|
|
|
/*{{{ void step_fx()*/
|
|
static int frig=0;
|
|
|
|
|
|
void step_fx()
|
|
{
|
|
int i;
|
|
big_bang *bang;
|
|
|
|
if (sfx_inited) {
|
|
for (i=0; i<MAX_PAZ_EXPLOSIONS; i++ ) {
|
|
bang=paz_explosions[i];
|
|
|
|
if (bang->inst->enable)
|
|
step_bang ( bang );
|
|
}
|
|
}
|
|
else
|
|
sfx_init();
|
|
}
|
|
|
|
/*}}} */
|
|
|