Files
TeslaRel410/sda4/DPL3RLS/EXAMPLES/TESTF15.C
T
CydandClaude Fable 5 db7745fcd0 sda4: commit the Glaze developer hard-drive dump
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>
2026-07-04 19:41:15 -05:00

574 lines
13 KiB
C++

/*
FILE : testf15.c
PROJECT : pxpl5 renderer example - F15 squadron
Author : Phil Atkin
(C) Division Ltd 1994.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <math.h>
#include "dpl5.h"
#include "boot.h"
#include "startup.h"
#include "spline.h"
#include "camera.h"
char *progname;
int860 link_A, link_B;
extern int magicLeftVal,
magicRightVal;
/*{{{ void eyeStuff ( VIEW *view )*/
void eyeStuff ( VIEW *view, int left )
{
float scale=1.0;
PAZidMatrix(view->f);
PAZidMatrix(view->b);
if (left) scale *= -1.0f;
if (left != (-1))
PAZtranslatePair (view->f, view->b, scale*1.275, 0, 0 );
PAZrotatePair (view->f, view->b, 180, PAZ_Y );
PAZtranslatePair (view->f, view->b, 0, 0, -102 );
if (left == (-1)) view->shift_x=0.0;
else if (left) view->shift_x=0.2147;
else view->shift_x=-0.2147;
/* view->shift_y = 0.0f; */
PAZwriteView ( view );
}
/*}}} */
#define MAX_PLANES 5
static int planes_inited=0;
static int camera_inited=0;
cntl_point *splinehead=NULL;
static float flight_t;
static MATRIX flight_m;
typedef struct s_plane {
cntl_point *cntl;
float t;
MATRIX orig;
} plane_cntl_type;
plane_cntl_type plane_cntl[16];
static void check_matrix ( MATRIX m, char *s )
{
MATRIX tmp;
MATRIX res;
float hyp;
int i, j;
PAZinvert ( tmp, m );
PAZconcat ( res, m, tmp, 1 );
for (i=0; i<4; i++ ) {
for (j=0; j<4; j++ ) {
float t=res[i][j];
hyp+=t*t;
}
}
if ((hyp < 3.99f) || (hyp > 4.01f)) {
printf("MATRIX %s >>>>>\n", s );
printf ( " [ %3.3f, %3.3f, %3.3f, %3.3f ]\n", m[0][0], m[0][1], m[0][2], m[0][3] );
printf ( " [ %3.3f, %3.3f, %3.3f, %3.3f ]\n", m[1][0], m[1][1], m[1][2], m[1][3] );
printf ( " [ %3.3f, %3.3f, %3.3f, %3.3f ]\n", m[2][0], m[2][1], m[2][2], m[2][3] );
printf ( " [ %3.3f, %3.3f, %3.3f, %3.3f ]\n", m[3][0], m[3][1], m[3][2], m[3][3] );
printf("concat with inverse %s >>>>>\n", s );
printf ( " [ %3.3f, %3.3f, %3.3f, %3.3f ]\n", res[0][0], res[0][1], res[0][2], res[0][3] );
printf ( " [ %3.3f, %3.3f, %3.3f, %3.3f ]\n", res[1][0], res[1][1], res[1][2], res[1][3] );
printf ( " [ %3.3f, %3.3f, %3.3f, %3.3f ]\n", res[2][0], res[2][1], res[2][2], res[2][3] );
printf ( " [ %3.3f, %3.3f, %3.3f, %3.3f ]\n", res[3][0], res[3][1], res[3][2], res[3][3] );
}
}
static float atan2deg ( float dz, float dx )
{
float angle;
if ((dx*dx) < 0.0001f) {
angle=(dz>0) ? 90.0f : -90.0f;
return angle;
}
else {
return (180.0f / 3.1415926535f) * atan2 ( dz, dx );
/*
if (dx>0)
return angle;
else
return 180.0f + angle;
*/
}
}
static void xformpoint ( POINT q, POINT p, MATRIX m )
{
POINT r;
int i;
for (i=0; i<4; i++ ) {
r[i]=(p[0]*m[0][i])+
(p[1]*m[1][i])+
(p[2]*m[2][i])+
(p[3]*m[3][i]);
}
memcpy ( q, r, sizeof(POINT));
}
void look_at ( VIEW *v, float *from, float *at, float z_spin )
{
/* construct a view from 2 points */
float dx, dy, dz;
float px, py, pz;
float thetax, thetay, thetaz;
float yaw, roll;
MATRIX m;
POINT p, q;
/* put 'at' at origin, construct a vector from 'from' */
px=from[0]; py=from[1]; pz=from[2];
dx=at[0]-px;
dy=at[1]-py;
dz=at[2]-pz;
thetaz=0.0f;
thetay=0.0f;
thetax=0.0f;
p[0]=dx;
p[1]=dy;
p[2]=dz;
p[3]=1;
yaw=-atan2deg ( dz, dx );
PAZidMatrix ( m );
PAZrotate ( m, -yaw, PAZ_Y, 1 );
xformpoint ( q, p, m );
roll=atan2deg(q[1], q[0] );
/* project onto x-z plane, assuming camera is initially looking down -z */
PAZidMatrix ( v->f );
/* apply angles to matrix */
PAZrotate ( v->f, z_spin, PAZ_Z, 1 );
PAZrotate ( v->f, roll, PAZ_X, 1 );
PAZrotate ( v->f, yaw-90.0f, PAZ_Y, 1 );
PAZtranslate( v->f, px, py, pz, 1 );
}
float evalx, evaly, evalz;
float tx, ty, tz, theta=0, dtheta=0, flight_r;
static float camera_t=0.0f;
static cntl_point *camerahead=NULL;
void cameradicking ( VIEW *eye,
INSTANCE *look_at_me,
float scale_fac,
float dt )
{
cntl_point *p=camerahead;
float t=camera_t;
float px, py, pz, rx, ry, rz;
POINT evalp;
if (camera_inited == 0) {
camera_inited=1;
p=init_splines("camera.spl");
t=0;
}
px=eval(p->x_pos_cubic, t );
py=eval(p->y_pos_cubic, t );
pz=eval(p->z_pos_cubic, t );
rx=eval(p->x_rot_cubic, t );
ry=eval(p->y_rot_cubic, t );
rz=eval(p->z_rot_cubic, t );
camerahead=walk_spline ( p, &t, dt );
camera_t=t;
/* we have wobbled the spline according to the file - now build the
view matrix */
eye->f[3][0]=px+look_at_me->f[3][0];
eye->f[3][1]=py+look_at_me->f[3][1];
eye->f[3][2]=pz+look_at_me->f[3][2];
evalp[0]=evalx;
evalp[1]=evaly;
evalp[2]=evalz;
/*
look_at ( eye, &eye->f[3][0], &look_at_me->f[3][0], rz );
*/
look_at ( eye, &eye->f[3][0], evalp, rz );
PAZwriteViewMatrix ( eye );
/* check_matrix ( eye->f, "view" ); */
}
void planedicking ( INSTANCE *inst, int planeId,
float scale, float dt, float dplane )
{
float px, py, pz, rx, ry, rz;
cntl_point *p;
float t;
int i;
MATRIX camera_target;
if (planes_inited == 0) {
planes_inited=1;
splinehead=init_splines("planes.spl");
for (i=1; i<MAX_PLANES; i++) {
float angle;
float fi=(float) i;
angle=fi * (3.1415926f * 2.0f) / (MAX_PLANES-1);
plane_cntl[i].cntl=splinehead;
plane_cntl[i].t=fi * dplane;
PAZidMatrix ( plane_cntl[i].orig );
PAZtranslate ( plane_cntl[i].orig,
10.3f*cos(angle), 0, 11.7f*sin(angle), 1 );
}
PAZidMatrix ( plane_cntl[0].orig );
plane_cntl[0].cntl=splinehead;
plane_cntl[0].t=dplane;
}
p=plane_cntl[planeId].cntl;
t=plane_cntl[planeId].t;
PAZidMatrix ( inst->f );
px=eval(p->x_pos_cubic, t );
py=eval(p->y_pos_cubic, t );
pz=eval(p->z_pos_cubic, t );
rx=eval(p->x_rot_cubic, t );
ry=eval(p->y_rot_cubic, t );
rz=eval(p->z_rot_cubic, t );
plane_cntl[planeId].cntl=walk_spline ( p, &plane_cntl[planeId].t, dt );
PAZscale ( inst->f, scale, scale, scale, 1 );
if (planeId == 0) {
PAZidMatrix ( camera_target );
PAZscale ( camera_target, scale, scale, scale, 1 );
}
/* the above scale should have brought us up to 1.0 ish in plane space */
/* now apply the spline */
PAZtranslate ( inst->f, px, py, pz, 1 );
PAZrotate ( inst->f, rz, PAZ_Z, 1 );
PAZrotate ( inst->f, rx, PAZ_X, 1 );
PAZrotate ( inst->f, ry, PAZ_Y, 1 );
PAZconcat ( inst->f, inst->f, plane_cntl[planeId].orig, 1 );
if (planeId==0) {
float rad=theta*3.1415926535f/180.0f;
theta+=dtheta;
tx=flight_r*cos(rad);
tz=flight_r*sin(rad);
}
PAZrotate ( inst->f, 180.0f-theta, PAZ_Y, 1 );
PAZtranslate ( inst->f, tx, 0, tz, 1 );
PAZscale ( inst->f, 6, 6, 6, 1 );
if (planeId == 0) {
PAZconcat ( camera_target, camera_target, plane_cntl[planeId].orig, 1 );
PAZrotate ( camera_target, 180.0f-theta, PAZ_Y, 1 );
PAZtranslate ( camera_target, tx, 0, tz, 1 );
PAZscale ( camera_target, 6, 6, 6, 1 );
evalx=camera_target[3][0];
evaly=camera_target[3][1];
evalz=camera_target[3][2];
}
}
void squadron_antics ( INSTANCE **planes, VIEW *eye, VIEW *rye, float scale_fac, int base, int times )
{
float theta;
int i, j;
float then, now;
if (rye == NULL)
eyeStuff ( eye, -1 );
else {
eyeStuff ( eye, 0 );
eyeStuff ( rye, 1 );
}
flight_r=26000;
dtheta=0.13;
for (i=base; i<times; i++) {
int nulls=0;
for (j=0; j<MAX_PLANES; j++) {
planedicking ( planes[j], j,
scale_fac, (j/392.0f)+0.034f, (j/283.0f)+0.007f );
PAZwriteMatrix ( planes[j] );
}
cameradicking(eye, planes[0], scale_fac, 0.02f );
PAZrenderScene();
}
}
/*{{{ char *makeVizName ( char *name )*/
char vizStr [256];
char *makeVizName ( char *name )
{
char *root;
if ((root=getenv("VIZPATH")) == NULL)
return(name);
else {
strcpy ( vizStr, root );
strcat ( vizStr, name );
return ( vizStr );
}
}
/*}}} */
/*{{{ char *makeTexName ( char *name )*/
char texStr [256];
char *makeTexName ( char *name )
{
char *root;
if ((root=getenv("TEXTURE")) == NULL)
return(name);
else {
strcpy ( vizStr, root );
strcat ( vizStr, name );
if (strchr(vizStr, '.')==NULL) {
strcat(vizStr, ".svt");
}
return ( vizStr );
}
}
/*}}} */
/*{{{ char *makedplName ( char *name )*/
char *makedplName ( char *dplstr, char *name )
{
char *root;
if ((root=getenv("DVIEWBIN")) == NULL)
return(name);
else {
strcpy ( dplstr, root );
strcat ( dplstr, name );
return ( dplstr );
}
}
/*}}} */
/*{{{ int env2hex ()*/
int env2hex ( char *env_str, int default_v )
{
char *s;
int v;
if (s = getenv(env_str)) {
if (sscanf(s, "%x", &v) == 1) {
return v;
}
}
printf ("Defaulting on %s to 0x%x\n", env_str, default_v );
return default_v;
}
/*}}} */
/*{{{ static OBJECT *load_flames( char *fname )*/
static OBJECT *load_flames( char *fname )
{
OBJECT *flame;
FILE *fp=fopen(makeTexName(fname), "rb" );
int texels[32];
int total_texels=0, n_read;
if (fp) {
printf ("load flames\n" );
for (n_read=fread ( texels, 1, 32*4, fp ); n_read; n_read=fread(texels,1,32*4,fp )) {
PAZfxtexels ( texels, 32 );
total_texels+=32;
}
fclose(fp);
}
printf ( "%d texels read\n", total_texels );
flame=PAZcreateObject ( makeVizName("flame.v2z"), makeTexName );
return flame;
}
/*}}} */
/*{{{ int nain ( int argc, char *argv[])*/
int nain ( int argc, char *argv[])
{
LIGHTSOURCE *bulb1, *bulb2, *bulb3, *bulb4, *bulb5, *bulb6;
INSTANCE *planes[MAX_PLANES];
INSTANCE *groundinst[25];
OBJECT *obj;
OBJECT *groundobj[25];
SCENE *s;
VIEW *eye, *rye;
OBJECT *F15, *F16, *flames;
float t, scale_fac=0.1;
char *objname;
int g, i, j, made, ramp;
s = initialize_all ( 0, -1, &eye, &rye );
sscanf(argv[1], "%f", &scale_fac );
PAZfog ( 1, 15000.0f, 26244.0f, 0.4, 0.5, 0.6 );
flames=load_flames("allovem.svt");
printf ("Making hills\n" );
g=0;
for (i=0; i<5; i++) {
for (j=0; j<5; j++) {
INSTANCE *terrinst;
OBJECT *terrobj;
char hilly[256];
sprintf(hilly, "terr%1d%1d.b2z", i*2, j*2 );
terrobj=PAZcreateObject(makeVizName(hilly), makeTexName);
terrinst=PAZcreateInstance();
terrinst->enable=1;
terrinst->obj=terrobj;
PAZwriteInstance ( terrinst );
PAZscale ( terrinst->f,
10*scale_fac, 0.41*scale_fac, 10*scale_fac, 1 );
PAZtranslate ( terrinst->f, 10.0, -14*scale_fac, 10.0, 1 );
PAZwriteMatrix ( terrinst );
groundobj[g]=terrobj;
groundinst[g]=terrinst;
g++;
}
}
printf ("Made hills\n" );
printf ("Making sky\n" );
{
OBJECT *skyobj;
INSTANCE *skyinst;
skyobj=PAZcreateObject(makeVizName("mtl_frig.v2z"), makeTexName);
skyinst=PAZcreateInstance();
skyinst->obj=skyobj;
skyinst->enable=1;
PAZscalePair ( skyinst->f, skyinst->b,
50*scale_fac, 50*scale_fac, 50*scale_fac );
PAZtranslatePair ( skyinst->f, skyinst->b, 0, 8*scale_fac, 0 );
PAZwriteInstance ( skyinst );
}
F15=PAZcreateObject ( makeVizName("F15.v2z"), makeTexName );
F16=PAZcreateObject ( makeVizName("F16.v2z"), makeTexName );
for (i=0; i< MAX_PLANES; i++) {
INSTANCE *p=(planes[i]=PAZcreateInstance());
if ((i&1) ==0)
p->obj=F15;
else
p->obj=F16;
p->enable=1;
PAZidMatrixPair ( p->f, p->b );
PAZwriteInstance ( p );
}
/* create 3 light bulbs */
bulb1=PAZcreateLight ();
PAZinitLight ( bulb1, light_directional, 0.99, 0.99, 0.79, 0, 1, 0 );
PAZwriteLight ( bulb1 );
bulb2=PAZcreateLight ();
PAZinitLight ( bulb2, light_ambient, 0.2, 0.3, 0.4, 0, 0, 0 );
PAZwriteLight ( bulb2 );
PAZsetBackGND ( 0.2, 0.3, 0.6 );
while (1) {
squadron_antics ( planes, eye, rye, scale_fac, 0, 1000 );
}
}
/*}}} */
/*{{{ int main ( int argc, char *argv[] )*/
int main ( int argc, char *argv[] )
{
link_A= 1;
link_B=-1;
progname=argv[0];
if (argc < 3) {
printf ("usage %s: <scale> <v2zfile>\n", argv[0] );
exit(666);
}
else {
char dplStr1 [256];
char dplStr2 [256];
magicLeftVal =env2hex("LEFTMAGIC", 0x3201);
magicRightVal=env2hex("RIGHTMAGIC", 0x3201);
near_clip=25.6/2;
far_clip =52428.8/2;
size_from_magic ( magicLeftVal );
start_dView ( makedplName ( dplStr1, "pp5mon2.btl"),
NULL,
makedplName ( dplStr2, "pazpl5.mng"),
env2hex("TRANSPUTER", 0x150), 1, -1 );
nain ( argc, argv );
}
}
/*}}} */