From 8b08533e3536d08d3d733aa424069f9a8d10300c Mon Sep 17 00:00:00 2001 From: Ian C Date: Tue, 23 Oct 2018 14:35:41 +0000 Subject: Added road demo. --- xd.c | 238 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 235 insertions(+), 3 deletions(-) (limited to 'xd.c') diff --git a/xd.c b/xd.c index 9f7a037..44a2ef0 100644 --- a/xd.c +++ b/xd.c @@ -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 */ -- cgit v1.2.3