diff options
| author | Ian C <ianc@noddybox.co.uk> | 2018-10-23 14:35:41 +0000 | 
|---|---|---|
| committer | Ian C <ianc@noddybox.co.uk> | 2018-10-23 14:35:41 +0000 | 
| commit | 8b08533e3536d08d3d733aa424069f9a8d10300c (patch) | |
| tree | 0f7f5726d9e05e7c798ed33abeea67706e7a48e5 | |
| parent | 74f15a9e50bb1bac10ff87da83214fdeb6f9b3dd (diff) | |
Added road demo.
| -rw-r--r-- | xd.c | 238 | 
1 files changed, 235 insertions, 3 deletions
| @@ -173,10 +173,11 @@ static void	FollowDemo(void);  static void	CatwalkDemo(void);  static void	GravityDemo(void);  static void	SnowDemo(void); +static void	RoadDemo(void);  /* ---------------------------------------- GLOBAL VARS  */ -#define NO_DEMOS	19 +#define NO_DEMOS	20  static int		demo=NO_DEMOS-1; @@ -279,6 +280,11 @@ static DemoInfo		demotbl[NO_DEMOS]=  				SnowDemo,  				UsesPixmap  			    }, +			    { +				"Road Demo", +				RoadDemo, +				UsesPixmap +			    },  			};  /* ---------------------------------------- X11 VARS @@ -304,6 +310,7 @@ static unsigned long		blue;  static int			mouse_x;  static int			mouse_y;  static unsigned int		mouse_b; +static KeySym			last_key = XK_VoidSymbol;  static double			sintab[3600];  static double			costab[3600]; @@ -448,6 +455,10 @@ int main(int argc, char *argv[])  		    HandleKey(&ev.xkey);  		    break; +		case KeyRelease: +		    last_key = XK_VoidSymbol; +		    break; +  		/*  		case ButtonPress:  		    HandleMouse(ev.xbutton.x,ev.xbutton.y, @@ -537,6 +548,13 @@ static void Bounce(int *x, int *y, int *ix, int *iy)      }  } +static double SgnF(double a) +{ +    if (a < 0.0) return -1.0; +    if (a > 0.0) return 1.0; +    return 0.0; +} +  /* ---------------------------------------- X11 UTILS  */ @@ -599,7 +617,7 @@ static void OpenX(void)  	 KeyPressMask|ButtonPressMask|ButtonReleaseMask|  	 	PointerMotionMask|ExposureMask);      */ -    XSelectInput(disp,win,KeyPressMask); +    XSelectInput(disp,win,KeyPressMask|KeyReleaseMask);      XStoreName(disp,win,demotbl[demo].name); @@ -812,7 +830,9 @@ static void SetCol(unsigned long col)  static void HandleKey(XKeyEvent *key)  { -    switch(XLookupKeysym(key,0)) +    KeySym sym; + +    switch((sym = XLookupKeysym(key,0)))      {  	case XK_Prior:  	    demo--; @@ -834,6 +854,7 @@ static void HandleKey(XKeyEvent *key)  	    break;  	default: +	    last_key = sym;  	    break;      }  } @@ -4288,6 +4309,217 @@ static void SnowDemo(void)  }  #undef SNOW_LINES +#undef SNOW_FLAKES + + +/* ---------------------------------------- ROAD DEMO + */ + +#define ROAD_NUM	5000 +#define ROAD_WIDTH	100 +#define ROAD_Z_INC	10 + +static void RoadDemo(void) +{ +    static int init = FALSE; + +    typedef struct +    { +    	double dx, dy; +    } Road; + +    static Road road[ROAD_NUM]; +    static double dx, dy; +    static double dxi, dyi; +    static int dcount; + +    int f,r; +    double x, y, z; +    double rx, ry, rz; +    double rx2, ry2, rz2; +    int max_y; +    double ang_y; +    double ang_x; + +    if (!init) +    { +	init=TRUE; + +	for(f = 0; f < ROAD_NUM; f++) +	{ +	    if (dcount == 0 && dx == 0 && dy == 0) +	    { +	    	dcount = RND2(20, 500); +		dx = 0; +		dy = 0; +		dxi = RND(10) / 40.0 - 0.125; +		dyi = RND(10) / 80.0 - 0.065; +	    } +	    else +	    { +		if (dcount) +		{ +		    dcount--; + +		    if (dx < ROAD_Z_INC / 2.0  && dx > -ROAD_Z_INC / 2.0) +		    { +			dx += dxi; +		    } + +		    if (dy < ROAD_Z_INC / 2.0 && dy > -ROAD_Z_INC / 2.0) +		    { +			dy += dyi; +		    } +		} +		else +		{ +		    double sdx = SgnF(dx); +		    double sdy = SgnF(dy); + +		    dx -= dxi; +		    dy -= dyi; + +		    if (SgnF(dx) != sdx) +		    { +		    	dx = 0; +			dy = 0; +		    } +		    else if (SgnF(dy) != sdy) +		    { +		    	dx = 0; +		    	dy = 0; +		    } +		} +	    } + +	    road[f].dx = dx; +	    road[f].dy = dy; +	} +    } + +    Cls(); + +    x = -ROAD_WIDTH / 2; +    y = 20.0; +    z = 10.0; +    max_y = height; + +    ang_x = atan(fabs(road[0].dy) / ROAD_Z_INC); + +    if (isnan(ang_x)) +    { +    	ang_x = 0; +    } +    else +    { +    	ang_x = DEG(ang_x) * 10.0; + +	if (road[0].dy > 0) +	{ +	    ang_x = -ang_x; +	} +    } + +    ang_y = atan(fabs(road[0].dx) / ROAD_Z_INC); + +    if (isnan(ang_y)) +    { +    	ang_y = 0; +    } +    else +    { +    	ang_y = DEG(ang_y) * 10.0; + +	if (road[0].dx > 0) +	{ +	    ang_y = -ang_y; +	} +    } + +    for(f = 0; f < ROAD_NUM; f++) +    { +    	XPoint xp; + +	x += road[f].dx; +	y += road[f].dy; +	z += ROAD_Z_INC; + +	RotateY(0, 0, 0, x, y, z, &rx, &ry, &rz, (int)ang_y); +	RotateX(0, 0, 0, rx, ry, rz, &rx2, &ry2, &rz2, (int)ang_x); + +	if (Project(rx2, ry2, rz2, &xp)) +	{ +	    if (xp.y < max_y) +	    { +		Plot(xp.x, xp.y, white); + +		Project(rx2 + ROAD_WIDTH, ry2, rz2, &xp); +		Plot(xp.x, xp.y, white); + +		max_y = xp.y; +	    } +	} + +	if (f < ROAD_NUM - 1) +	{ +	    road[f] = road[f + 1]; +	} +	else +	{ +	    if (dcount == 0 && dx == 0 && dy == 0) +	    { +	    	dcount = RND2(20, 500); +		dx = 0; +		dy = 0; +		dxi = RND(10) / 40.0 - 0.125; +		dyi = RND(10) / 80.0 - 0.065; +	    } +	    else +	    { +		if (dcount) +		{ +		    dcount--; + +		    if (dx < ROAD_Z_INC / 2.0  && dx > -ROAD_Z_INC / 2.0) +		    { +			dx += dxi; +		    } + +		    if (dy < ROAD_Z_INC / 2.0 && dy > -ROAD_Z_INC / 2.0) +		    { +			dy += dyi; +		    } +		} +		else +		{ +		    double sdx = SgnF(dx); +		    double sdy = SgnF(dy); + +		    dx -= dxi; +		    dy -= dyi; + +		    if (SgnF(dx) != sdx) +		    { +		    	dx = 0; +			dy = 0; +		    } +		    else if (SgnF(dy) != sdy) +		    { +		    	dx = 0; +		    	dy = 0; +		    } +		} +	    } + +	    road[f].dx = dx; +	    road[f].dy = dy; +	} +    } +} + +#undef ROAD_NUM +#undef ROAD_WIDTH +#undef ROAD_Z_INC  /* END OF FILE */ | 
