584 lines
18 KiB
C
584 lines
18 KiB
C
|
/*
|
||
|
* xcl.c
|
||
|
* Control-Line in a box
|
||
|
* Copyright (c) 2000 by Martin Berentsen <berentsen@sent5.uni-duisburg.de>
|
||
|
*
|
||
|
* change-log
|
||
|
* 0.4pl2 -> 0.5pl0 25/07/2000
|
||
|
* -singl command line option becomes to -count num
|
||
|
* 0.5pl0 -> 0.5pl1 02.02.2001
|
||
|
* bugs in -oldcolor and -randomstart option removed
|
||
|
*
|
||
|
* TODO as next:
|
||
|
* - a user defined speed for every used plane
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
#if !defined( lint ) && !defined( SABER )
|
||
|
static const char sccsid[] = "@(#)xcl.c 5.00 2000/11/01 xlockmore";
|
||
|
#endif
|
||
|
|
||
|
#define RAND(x) (((my_random() % x )- x/2)) /* random number around 0 */
|
||
|
#define ROTATEDELAY 20000 /* delay for view-model rotating */
|
||
|
#define STARTUPDELAY 5000 /* delay for the first calibration loop */
|
||
|
#define REGULATE 25 /* regulate delay every xx frames */
|
||
|
#define FRAMETIME 45000 /* time for one frame */
|
||
|
#define MINPLANES 1 /* define the min number of planes */
|
||
|
#define MAXCOUNT 30 /* define the max number of planes */
|
||
|
|
||
|
#ifdef STANDALONE
|
||
|
#define MODE_xcl
|
||
|
#define PROGCLASS "Xcl"
|
||
|
#define HACK_INIT init_xcl
|
||
|
#define HACK_DRAW draw_xcl
|
||
|
#define xcl_opts xlockmore_opts
|
||
|
#define DEFAULTS "*delay: 20000 \n" \
|
||
|
"*count: 2 \n"
|
||
|
#define UNIFORM_COLORS
|
||
|
#include "xlockmore.h" /* in xscreensaver distribution */
|
||
|
#else /* STANDALONE */
|
||
|
#include "xlock.h" /* in xlockmore distribution */
|
||
|
#endif
|
||
|
|
||
|
#ifdef WIN32
|
||
|
#include <sys/time.h>
|
||
|
#endif
|
||
|
|
||
|
#include "xcl.h" /* model line data file */
|
||
|
|
||
|
#ifdef MODE_xcl
|
||
|
|
||
|
/* all parameters are global */
|
||
|
static float speed[MAXCOUNT]; /* Speed in km/h */
|
||
|
static float speed_in; /* speed set by user */
|
||
|
static int frametime; /* time for one frame in usecs */
|
||
|
static int line_length; /* lines in mm*/
|
||
|
static float spectator; /* spectator distance from zero*/
|
||
|
static Bool viewmodel; /* shows one rotating model*/
|
||
|
static Bool oldcolor; /* use the old yellow/red color combination */
|
||
|
static Bool debug; /* debug modus */
|
||
|
static Bool automatic; /* automatic scale for fit into window */
|
||
|
static Bool randomstart; /* don't use the same start position */
|
||
|
static int random_pid;
|
||
|
|
||
|
|
||
|
#define DEF_SPEED_IN "105.0"
|
||
|
#define DEF_FRAMETIME "45000"
|
||
|
#define DEF_LINE_LENGTH "15910"
|
||
|
#define DEF_SPECTATOR "22000"
|
||
|
#define DEF_VIEWMODEL "False"
|
||
|
#define DEF_OLDCOLOR "False"
|
||
|
#define DEF_XCLDEBUG "False"
|
||
|
#define DEF_AUTOMATIC "True"
|
||
|
#define DEF_RANDOMSTART "False"
|
||
|
|
||
|
|
||
|
static XrmOptionDescRec opts[] =
|
||
|
{
|
||
|
{(char *) "-speed", (char *) ".xcl.speed", XrmoptionSepArg, (caddr_t) NULL},
|
||
|
{(char *) "-frametime", (char *) ".xcl.frametime", XrmoptionSepArg, (caddr_t) NULL},
|
||
|
{(char *) "-line_length", (char *) ".xcl.line_length", XrmoptionSepArg, (caddr_t) NULL},
|
||
|
{(char *) "-spectator", (char *) ".xcl.spectator", XrmoptionSepArg, (caddr_t) NULL},
|
||
|
{(char *) "-viewmodel", (char *) ".xcl.viewmodel", XrmoptionNoArg, (caddr_t) "on"},
|
||
|
{(char *) "+viewmodel", (char *) ".xcl.viewmodel", XrmoptionNoArg, (caddr_t) "off"},
|
||
|
{(char *) "-oldcolor", (char *) ".xcl.oldcolor", XrmoptionNoArg, (caddr_t) "on"},
|
||
|
{(char *) "+oldcolor", (char *) ".xcl.oldcolor", XrmoptionNoArg, (caddr_t) "off"},
|
||
|
{(char *) "-xcldebug", (char *) ".xcl.xcldebug", XrmoptionNoArg, (caddr_t) "on"},
|
||
|
{(char *) "+xcldebug", (char *) ".xcl.xcldebug", XrmoptionNoArg, (caddr_t) "off"},
|
||
|
{(char *) "-automatic", (char *) ".xcl.automatic", XrmoptionNoArg, (caddr_t) "on"},
|
||
|
{(char *) "+automatic", (char *) ".xcl.automatic", XrmoptionNoArg, (caddr_t) "off"},
|
||
|
{(char *) "-randomstart", (char *) ".xcl.randomstart", XrmoptionNoArg, (caddr_t) "on"},
|
||
|
{(char *) "+randomstart", (char *) ".xcl.randomstart", XrmoptionNoArg, (caddr_t) "off"}
|
||
|
};
|
||
|
static argtype vars[] =
|
||
|
{
|
||
|
{(void *) & speed_in, (char *) "speed", (char *) "Speed", (char *) DEF_SPEED_IN, t_Float},
|
||
|
{(void *) & frametime, (char *) "frametime", (char *) "frametime", (char *) DEF_FRAMETIME, t_Int},
|
||
|
{(void *) & line_length, (char *) "line_length", (char *) "Line_length", (char *) DEF_LINE_LENGTH, t_Int},
|
||
|
{(void *) & spectator, (char *) "spectator", (char *) "Spectator", (char *) DEF_SPECTATOR, t_Float},
|
||
|
{(void *) & viewmodel, (char *) "viewmodel", (char *) "Viewmodel", (char *) DEF_VIEWMODEL, t_Bool},
|
||
|
{(void *) & oldcolor, (char *) "oldcolor", (char *) "Oldcolor", (char *) DEF_OLDCOLOR, t_Bool},
|
||
|
{(void *) & debug, (char *) "xcldebug", (char *) "Xcldebug", (char *) DEF_XCLDEBUG, t_Bool},
|
||
|
{(void *) & automatic, (char *) "automatic", (char *) "Automatic", (char *) DEF_AUTOMATIC, t_Bool},
|
||
|
{(void *) & randomstart, (char *) "randomstart", (char *) "Randomstart", (char *) DEF_RANDOMSTART, t_Bool}
|
||
|
};
|
||
|
static OptionStruct desc[] =
|
||
|
{
|
||
|
{(char *) "-speed num", (char *) "speed for the planes in km/h "},
|
||
|
{(char *) "-frametime num", (char *) "time for one frame on the screen in usecs "},
|
||
|
{(char *) "-line_length num", (char *) "distance between the pilot and the plane in mm "},
|
||
|
{(char *) "-spectator num", (char *) "distance between spectator and pilot in mm"},
|
||
|
{(char *) "-/+viewmodel", (char *) "turn on/off an anim view of one model"},
|
||
|
{(char *) "-/+oldcolor", (char *) "turn on/off the old yellow/red combination"},
|
||
|
{(char *) "-/+xcldebug", (char *) "turn on/off some timing information"},
|
||
|
{(char *) "-/+automatic", (char *) "turn on/off auto scale for fit into the window"},
|
||
|
{(char *) "-/+randomstart", (char *) "turn on/off a random start point for models at startup"}
|
||
|
};
|
||
|
|
||
|
ModeSpecOpt xcl_opts =
|
||
|
{sizeof opts / sizeof opts[0], opts, sizeof vars / sizeof vars[0], vars, desc};
|
||
|
|
||
|
#ifdef USE_MODULES /* for xlockmore */
|
||
|
ModStruct xcl_description =
|
||
|
{"xcl", "init_xcl", "draw_xcl", "release_xcl",
|
||
|
"draw_xcl", "init_xcl", (char *) NULL, &xcl_opts ,
|
||
|
20000, -3, 1, 1, 64, 1.0, "",
|
||
|
"Shows a control line combat model race", 0, NULL};
|
||
|
#endif
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
int planes; /* number of planes viewed*/
|
||
|
int lines; /* number of lines counted in model */
|
||
|
double az[MAXCOUNT]; /* azimuth of plane */
|
||
|
double el[MAXCOUNT]; /* elevation of plane */
|
||
|
int width;
|
||
|
int height;
|
||
|
int mid_x;
|
||
|
int mid_y;
|
||
|
float Alpha; /* rotate.1 */
|
||
|
float Beta; /* rotate.2 */
|
||
|
float Gamma; /* rotate.3 */
|
||
|
float Vx; /* width from zero in X */
|
||
|
float Vy; /* width from zero in Y */
|
||
|
float Vz; /* width from zero in Z */
|
||
|
float G; /* ZOOM */
|
||
|
float Ca,Cb,Cc,Sa,Sb,Sc; /* only for faster calculation */
|
||
|
float Bx,By ;
|
||
|
struct timeval tv1;
|
||
|
double time1, time2, time3; /* calibrate time */
|
||
|
int drawtime;
|
||
|
double alpha[MAXCOUNT]; /* direction */
|
||
|
double omega_const[MAXCOUNT]; /* constant omega speed */
|
||
|
double delta_az[MAXCOUNT];
|
||
|
double delta_el[MAXCOUNT];
|
||
|
int turn[MAXCOUNT];
|
||
|
int turn_direction[MAXCOUNT];
|
||
|
int random_pid;
|
||
|
long planecolor[MAXCOUNT],bg; /* used colours */
|
||
|
GC gc[MAXCOUNT];
|
||
|
GC erase_gc;
|
||
|
XSegment *xseg[MAXCOUNT];
|
||
|
XSegment *xseg_old[MAXCOUNT];
|
||
|
int xcldelay;
|
||
|
int no_preset;
|
||
|
} xclstruct;
|
||
|
|
||
|
static xclstruct *xcls = (xclstruct *) NULL;
|
||
|
|
||
|
static int my_random(void) /* not really good, but it works */
|
||
|
{
|
||
|
static int number;
|
||
|
number -= random_pid;
|
||
|
return ( 0x0fff & (number));
|
||
|
}
|
||
|
|
||
|
static int countlines(void)
|
||
|
{
|
||
|
int array;
|
||
|
int count = 0;
|
||
|
for(array = 0;array<LINEARRAYS;array++) {
|
||
|
count += model_data2[array][0] - 1;
|
||
|
}
|
||
|
return(count);
|
||
|
}
|
||
|
|
||
|
static void um2(int X, int Y, int Z, xclstruct *dp)
|
||
|
{
|
||
|
float X2,X3,X4,Y1,Y3,Y4,Z1,Z2,Z4;
|
||
|
|
||
|
Y1 = dp->Ca * Y - dp->Sa * Z;
|
||
|
Z1 = dp->Sa * Y + dp->Ca * Z;
|
||
|
X2 = dp->Cb * X - dp->Sb * Z1;
|
||
|
Z2 = dp->Sb * X + dp->Cb * Z1;
|
||
|
X3 = dp->Cc * X2 - dp->Sc * Y1;
|
||
|
Y3 = dp->Sc * X2 + dp->Cc * Y1;
|
||
|
X4 = X3 + dp->Vx;
|
||
|
Y4 = Y3 + dp->Vy;
|
||
|
Z4 = Z2 + dp->Vz;
|
||
|
|
||
|
dp->Bx = dp->mid_x + (-X4 / Y4 * dp->G);
|
||
|
dp->By = dp->mid_y - (-Z4 / Y4 * dp->G);
|
||
|
}
|
||
|
|
||
|
static void view_3d(XSegment *xseg, xclstruct *dp)
|
||
|
{
|
||
|
int count = 0;
|
||
|
int I,J;
|
||
|
float BX [ENDPOINTS];
|
||
|
float BY [ENDPOINTS];
|
||
|
|
||
|
dp->Ca = cos(dp->Alpha);
|
||
|
dp->Cb = cos(dp->Beta);
|
||
|
dp->Cc = cos(dp->Gamma);
|
||
|
dp->Sa = sin(dp->Alpha);
|
||
|
dp->Sb = sin(dp->Beta);
|
||
|
dp->Sc = sin(dp->Gamma);
|
||
|
|
||
|
for(I = 0; I < ENDPOINTS; I++) {
|
||
|
um2( model_data1 [ I * 3 + 0], model_data1 [ I * 3 + 1],
|
||
|
model_data1 [ I * 3 + 2],dp);
|
||
|
BX [I] = dp->Bx;
|
||
|
BY [I] = dp->By;
|
||
|
}
|
||
|
for (I = 0; I < LINEARRAYS; I++) {
|
||
|
for (J = 1; J < model_data2[I][0]; J++) {
|
||
|
xseg[count].x1 = (short) BX[(model_data2[I][J])-1];
|
||
|
xseg[count].y1 = (short) BY[(model_data2[I][J])-1]+(dp->mid_y/2);
|
||
|
xseg[count].x2 = (short) BX[(model_data2[I][J+1])-1];
|
||
|
xseg[count].y2 = (short) BY[(model_data2[I][J+1])-1]+(dp->mid_y/2);
|
||
|
count++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static long get_color(Display *dpy, char *color, XColor *final_color)
|
||
|
{
|
||
|
XColor cdef;
|
||
|
Colormap cmap;
|
||
|
cmap = DefaultColormap(dpy,DefaultScreen(dpy));
|
||
|
|
||
|
if (!XParseColor(dpy, cmap, color, &cdef) ||
|
||
|
!XAllocColor(dpy, cmap, &cdef))
|
||
|
{
|
||
|
(void) fprintf(stderr, "Color \"%s\" wasn't found\n", color);
|
||
|
}
|
||
|
|
||
|
if (final_color != NULL) *final_color = cdef; /* copy the final color. */
|
||
|
|
||
|
return(cdef.pixel);
|
||
|
}
|
||
|
|
||
|
static Bool get_GC(Display *dpy,Window win,GC *gc,long color)
|
||
|
{
|
||
|
unsigned long valuemask = 0; /*ignore XGCvalues and use defaults */
|
||
|
XGCValues values;
|
||
|
unsigned int line_width = 1;
|
||
|
int line_style = LineSolid; /* LineOnOffDash;*/
|
||
|
int cap_style = CapRound;
|
||
|
int join_style = JoinRound;
|
||
|
|
||
|
if ((*gc = XCreateGC(dpy, win, valuemask , &values)) == None)
|
||
|
return False;
|
||
|
XSetForeground(dpy, *gc, color);
|
||
|
|
||
|
XSetLineAttributes(dpy, *gc, line_width, line_style,
|
||
|
cap_style, join_style);
|
||
|
return True;
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
free_xcl(Display *display, xclstruct *dp)
|
||
|
{
|
||
|
int plane;
|
||
|
|
||
|
for (plane = 0; plane < dp->planes; plane++) {
|
||
|
if (dp->xseg[plane] != NULL) {
|
||
|
free(dp->xseg[plane]);
|
||
|
dp->xseg[plane] = (XSegment *) NULL;
|
||
|
}
|
||
|
if (dp->xseg_old[plane] != NULL) {
|
||
|
free(dp->xseg_old[plane]);
|
||
|
dp->xseg_old[plane] = (XSegment *) NULL;
|
||
|
}
|
||
|
if (dp->gc[plane] != None) {
|
||
|
XFreeGC(display, dp->gc[plane]);
|
||
|
dp->gc[plane] = None;
|
||
|
}
|
||
|
}
|
||
|
if (dp->erase_gc != None) {
|
||
|
XFreeGC(display, dp->erase_gc);
|
||
|
dp->erase_gc = None;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void release_xcl(ModeInfo * mi)
|
||
|
{
|
||
|
if (xcls != NULL) {
|
||
|
int screen;
|
||
|
for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++)
|
||
|
free_xcl(MI_DISPLAY(mi), &xcls[screen]);
|
||
|
free(xcls);
|
||
|
xcls = (xclstruct *) NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void init_xcl(ModeInfo * mi)
|
||
|
{
|
||
|
Display *display = MI_DISPLAY(mi);
|
||
|
int i; /* scratch */
|
||
|
xclstruct *dp;
|
||
|
|
||
|
if (xcls == NULL) {
|
||
|
if ((xcls = (xclstruct *) calloc(MI_NUM_SCREENS(mi),
|
||
|
sizeof (xclstruct))) == NULL)
|
||
|
return;
|
||
|
}
|
||
|
dp = &xcls[MI_SCREEN(mi)];
|
||
|
|
||
|
/* Update every time */
|
||
|
dp->width = MI_WIDTH(mi);
|
||
|
dp->height = MI_HEIGHT(mi);
|
||
|
dp->mid_x = (dp->width / 2);
|
||
|
dp->mid_y = (dp->height / 2);
|
||
|
|
||
|
if(dp->no_preset != 1) {
|
||
|
dp->no_preset = 1;
|
||
|
/* some presettings */
|
||
|
dp->planes = MI_COUNT(mi);
|
||
|
if (dp->planes < -MINPLANES) {
|
||
|
dp->planes = NRAND(-MI_COUNT(mi) -MINPLANES + 1) + MINPLANES;
|
||
|
} else if (dp->planes < MINPLANES) {
|
||
|
dp->planes = MINPLANES;
|
||
|
}
|
||
|
if(dp->planes > MAXCOUNT)
|
||
|
dp->planes = MAXCOUNT;
|
||
|
dp->Alpha = 0.0; /* rotate.1 */
|
||
|
dp->Beta = 0.0; /* rotate.2 */
|
||
|
dp->Gamma = 0.0; /* rotate.3 */
|
||
|
dp->Vx = 1; /* width from zero in X */
|
||
|
dp->Vy = 800; /* width from zero in Y */
|
||
|
dp->Vz = -300; /* width from zero in Z */
|
||
|
dp->G = 500.0; /* ZOOM */
|
||
|
dp->time3 = 1.0;
|
||
|
dp->drawtime = 25000;
|
||
|
dp->xcldelay = STARTUPDELAY;
|
||
|
for(i=0;i< dp->planes; i++) {
|
||
|
dp->az[i] = 2 * M_PI * i / (float)((dp->planes));
|
||
|
dp->el[i] = 0.0;
|
||
|
dp->alpha[i] = 0.75; /* direction */
|
||
|
dp->turn[i] = 0;
|
||
|
dp->turn_direction[i] = 1;
|
||
|
|
||
|
speed[i] = speed_in; /* see TODO */
|
||
|
}
|
||
|
|
||
|
random_pid = getpid(); /* goes here first for randomstart */
|
||
|
|
||
|
if(randomstart) {
|
||
|
for(i=0;i< dp->planes; i++) {
|
||
|
switch(i) {
|
||
|
case 0:
|
||
|
dp->az[0] += (random_pid % 31) / 5.0;
|
||
|
break;
|
||
|
default:
|
||
|
dp->az[i] = dp->az[0] + 2 * M_PI * i / (float)((dp->planes));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
dp->bg = MI_BLACK_PIXEL(mi);
|
||
|
|
||
|
if(MI_IS_MONO(mi))
|
||
|
for(i=0;i< dp->planes; i++) {
|
||
|
dp->planecolor[i] = MI_WHITE_PIXEL(mi);
|
||
|
}
|
||
|
else {
|
||
|
if(!oldcolor) {
|
||
|
for(i=0;i< dp->planes; i++) {
|
||
|
dp->planecolor[i] = MI_PIXEL(mi, NRAND(MI_NPIXELS(mi)));
|
||
|
}
|
||
|
}
|
||
|
else { /* with count >2 no so good */
|
||
|
for(i=0;i< dp->planes; i++) {
|
||
|
switch(i) {
|
||
|
case 0:
|
||
|
dp->planecolor[0] = get_color(display, (char *) "yellow",
|
||
|
(XColor *) NULL);
|
||
|
break;
|
||
|
case 1:
|
||
|
dp->planecolor[1] = get_color(display, (char *) "red",
|
||
|
(XColor *) NULL);
|
||
|
break;
|
||
|
default:
|
||
|
dp->planecolor[i] = MI_PIXEL(mi, NRAND(MI_NPIXELS(mi)));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(dp->erase_gc == NULL)
|
||
|
if (!get_GC(display, MI_WINDOW(mi), &(dp->erase_gc),dp->bg)) {
|
||
|
free_xcl(display, dp);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
dp->lines = countlines();
|
||
|
|
||
|
for(i=0;i< dp->planes; i++) {
|
||
|
if(dp->gc[i] == NULL)
|
||
|
if (!get_GC(display, MI_WINDOW(mi), &(dp->gc[i]),
|
||
|
dp->planecolor[i])) {
|
||
|
free_xcl(display, dp);
|
||
|
return;
|
||
|
}
|
||
|
dp->omega_const[i] = speed[i]/3.6 /line_length*1000.0;
|
||
|
|
||
|
if(dp->xseg[i] == NULL)
|
||
|
if ((dp-> xseg[i] = (XSegment *) malloc(sizeof(XSegment) *
|
||
|
dp->lines)) == NULL) {
|
||
|
free_xcl(display, dp);
|
||
|
return;
|
||
|
}
|
||
|
if(dp->xseg_old[i] == NULL)
|
||
|
if ((dp->xseg_old[i] = (XSegment *) malloc(sizeof(XSegment) *
|
||
|
dp->lines)) == NULL) {
|
||
|
free_xcl(display, dp);
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(MI_IS_VERBOSE(mi)) {
|
||
|
(void) printf("X control line combat in a box\n");
|
||
|
#if !defined( lint ) && !defined( SABER )
|
||
|
(void) printf("Version: %s\n",sccsid);
|
||
|
#endif
|
||
|
(void) printf("Line length: %gm\n",line_length/1000.0);
|
||
|
(void) printf("Speed %g km/h \n",speed[0]);
|
||
|
(void) printf("Lines per plane: %d\n",dp->lines);
|
||
|
(void) printf("Spectator at %gm\n",spectator/1000.0);
|
||
|
(void) printf("Try %g frames per Second (frametime: %dus)\n",
|
||
|
1000000.0/frametime,frametime);
|
||
|
(void) printf("Calibration at %d frames\n",REGULATE);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* clear the screen */
|
||
|
|
||
|
MI_CLEARWINDOW(mi);
|
||
|
|
||
|
(void) gettimeofday(&(dp->tv1),0);
|
||
|
dp->time1 = (double)dp->tv1.tv_sec +
|
||
|
(double)dp->tv1.tv_usec/(double)1000000;
|
||
|
|
||
|
dp->xcldelay = frametime;
|
||
|
}
|
||
|
|
||
|
void draw_xcl(ModeInfo * mi)
|
||
|
{
|
||
|
static int count = 0;
|
||
|
int i;
|
||
|
xclstruct *dp;
|
||
|
|
||
|
if (xcls == NULL)
|
||
|
return;
|
||
|
dp = &xcls[MI_SCREEN(mi)];
|
||
|
if (dp->erase_gc == None)
|
||
|
return;
|
||
|
|
||
|
MI_IS_DRAWN(mi) = True;
|
||
|
|
||
|
if(viewmodel == True)
|
||
|
{
|
||
|
dp->Vx = 1; /* movement in X (width,negativ)*/
|
||
|
if(dp->width < 900)
|
||
|
dp->Vy = 800*800/dp->width; /* Y (deep)*/
|
||
|
else
|
||
|
dp->Vy = 800*1200/dp->width; /* Y (deep)*/
|
||
|
dp->Vz = -300; /* Z (height) */
|
||
|
dp->G = 350.0; /* make it smaller when display is smaller */
|
||
|
dp->Alpha += 0.03;
|
||
|
dp->Beta += 0.006;
|
||
|
dp->Gamma += 0.009;
|
||
|
|
||
|
if (count != 0) {
|
||
|
XDrawSegments(MI_DISPLAY(mi),MI_WINDOW(mi),dp->erase_gc,
|
||
|
dp->xseg_old[0],dp->lines);
|
||
|
XDrawSegments(MI_DISPLAY(mi),MI_WINDOW(mi),dp->gc[0],
|
||
|
dp->xseg[0],dp->lines);
|
||
|
(void) usleep(ROTATEDELAY * 2);
|
||
|
}
|
||
|
(void) memcpy(dp->xseg_old[0],dp->xseg[0],sizeof(XSegment)*dp->lines);
|
||
|
view_3d(dp->xseg[0],dp);
|
||
|
count ++;
|
||
|
}
|
||
|
else {
|
||
|
if(automatic)
|
||
|
dp->G = dp->width / 2.1 ;
|
||
|
|
||
|
for(i=0;i<dp->planes;i++) {
|
||
|
(void) memcpy(dp->xseg_old[i],dp->xseg[i],sizeof(XSegment)*dp->lines);
|
||
|
|
||
|
dp->Alpha = - dp->alpha[i];
|
||
|
dp->Beta = - dp->el[i];
|
||
|
dp->Gamma = dp->az[i];
|
||
|
|
||
|
dp->Vx = -(int)(cos(dp->az[i]) * cos(dp->el[i]) * line_length);
|
||
|
dp->Vy = spectator -
|
||
|
(int)(sin(dp->az[i]) * cos(dp->el[i]) * line_length);
|
||
|
dp->Vz = (int)(sin(dp->el[i]) * line_length);
|
||
|
|
||
|
view_3d(dp->xseg[i],dp);
|
||
|
XDrawSegments(MI_DISPLAY(mi),MI_WINDOW(mi),dp->erase_gc,
|
||
|
dp->xseg_old[i],dp->lines);
|
||
|
XDrawSegments(MI_DISPLAY(mi),MI_WINDOW(mi),dp->gc[i],
|
||
|
dp->xseg[i],dp->lines);
|
||
|
}
|
||
|
|
||
|
XFlush(MI_DISPLAY(mi));
|
||
|
|
||
|
/* now move all planes */
|
||
|
for(i=0;i<dp->planes;i++) {
|
||
|
dp->delta_az[i] = cos(dp->alpha[i]) * dp->omega_const[i] *
|
||
|
frametime/1000000;
|
||
|
dp->delta_el[i] = sin(dp->alpha[i]) * dp->omega_const[i] *
|
||
|
frametime/1000000;
|
||
|
|
||
|
dp->az[i] -= dp->delta_az[i];
|
||
|
dp->el[i] -= dp->delta_el[i];
|
||
|
|
||
|
if (dp->el[i] >= 0.0)
|
||
|
switch (dp->turn[i]) {
|
||
|
case 0:
|
||
|
dp->turn_direction[i] *= -1;
|
||
|
dp->alpha[i] += 0.62831853 * dp->turn_direction[i];
|
||
|
dp->turn[i] ++;
|
||
|
break;
|
||
|
case 1:
|
||
|
case 2:
|
||
|
case 3:
|
||
|
case 4:
|
||
|
case 5:
|
||
|
dp->alpha[i] += 0.62831853 * dp->turn_direction[i];
|
||
|
dp->turn[i] ++;
|
||
|
break;
|
||
|
default:
|
||
|
dp->turn[i] ++;
|
||
|
break;
|
||
|
}
|
||
|
else
|
||
|
dp->turn[i] = 0;
|
||
|
if (dp->el[i] <= -(M_PI / 2.0))
|
||
|
{
|
||
|
dp->alpha[i] += M_PI;
|
||
|
dp->az[i] += M_PI;
|
||
|
/* el[i] = el[i] + (M_PI / 2.0) ; */
|
||
|
}
|
||
|
else
|
||
|
if(dp->turn[i] == 0)
|
||
|
dp->alpha[i] += (double)(RAND(600)) / 6283.0 * 2.0 * M_PI;
|
||
|
} /* for (i) */
|
||
|
|
||
|
count++;
|
||
|
|
||
|
(void) usleep(dp->xcldelay);
|
||
|
if((count % REGULATE) == 0) {
|
||
|
(void) gettimeofday(&(dp->tv1),0);
|
||
|
dp->time2 = (double)dp->tv1.tv_sec + (double)dp->tv1.tv_usec/
|
||
|
(double)1000000;
|
||
|
dp->time3 = dp->time2 - dp->time1;
|
||
|
dp->time1 = dp->time2;
|
||
|
dp->drawtime = (int) (dp->time3 * (1000000/REGULATE))
|
||
|
- dp->xcldelay;
|
||
|
if((dp->xcldelay = frametime - dp->drawtime) <= 0) {
|
||
|
dp->xcldelay = 10; /* 1 is possible xor xscreensaver mode */
|
||
|
}
|
||
|
if(debug == True)
|
||
|
(void) printf("t_draw: %d, t_delay: %d\n",dp->drawtime,
|
||
|
dp->xcldelay);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#endif /* MODE_xcl */
|