From 732032beb1c75cf84a56d4a14fc2d0cf824c6d20 Mon Sep 17 00:00:00 2001 From: Ian C Date: Fri, 26 Oct 2018 11:56:48 +0000 Subject: Added roller coaster demo. --- xd.c | 345 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 344 insertions(+), 1 deletion(-) diff --git a/xd.c b/xd.c index ba8b4fe..c37d1ef 100644 --- a/xd.c +++ b/xd.c @@ -174,10 +174,11 @@ static void CatwalkDemo(void); static void GravityDemo(void); static void SnowDemo(void); static void RoadDemo(void); +static void CoasterDemo(void); /* ---------------------------------------- GLOBAL VARS */ -#define NO_DEMOS 20 +#define NO_DEMOS 21 static int demo=NO_DEMOS-1; @@ -285,6 +286,11 @@ static DemoInfo demotbl[NO_DEMOS]= RoadDemo, UsesPixmap }, + { + "Coster Demo (RMB toggle mouselook)", + CoasterDemo, + UsesPixmap + }, }; /* ---------------------------------------- X11 VARS @@ -4577,4 +4583,341 @@ static void RoadDemo(void) #undef ROAD_Z_INC +/* ---------------------------------------- COASTER DEMO + */ + +#define COASTER_NUM 5000 +#define COASTER_WIDTH 30 +#define COASTER_Z_INC 10 +#define COASTER_BAR 20 +#define COASTER_POLE 200 +#define MIN_SPEED 2 +#define MAX_SPEED COASTER_Z_INC + +static void CoasterDemo(void) +{ + static int init = FALSE; + + typedef struct + { + double dx, dy; + int bar, pole; + } Coaster; + + static Coaster coaster[COASTER_NUM]; + static double dx, dy; + static double dxi, dyi; + static int dcount; + static int mouselook = FALSE; + static int counter = 0; + static double speed = MAX_SPEED; + static double start_z = 20.0; + + int f,r; + double x, y, z; + double rx, ry, rz; + double rx2, ry2, rz2; + double ang_y; + double ang_x; + XPoint last_xp1, last_xp2; + + if (!init) + { + init=TRUE; + + for(f = 0; f < COASTER_NUM; f++) + { + if (dcount == 0 && dx == 0 && dy == 0) + { + dcount = RND2(200, 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 < COASTER_Z_INC / 2.0 && dx > -COASTER_Z_INC / 2.0) + { + dx += dxi; + } + + if (dy < COASTER_Z_INC / 2.0 && dy > -COASTER_Z_INC / 2.0) + { + dy += dyi; + } + } + else + { + double sdx = SgnF(dx); + double sdy = SgnF(dy); + + if (dx != 0.0) + { + dx -= dxi; + } + + if (dy != 0.0) + { + dy -= dyi; + } + + if (SgnF(dx) != sdx) + { + dx = 0; + } + + if (SgnF(dy) != sdy) + { + dy = 0; + } + } + } + + coaster[f].dx = dx; + coaster[f].dy = dy; + + if ((counter % COASTER_BAR) == 0) + { + coaster[f].bar = TRUE; + } + else + { + coaster[f].bar = FALSE; + } + + if ((counter % COASTER_POLE) == 0) + { + coaster[f].pole = TRUE; + } + else + { + coaster[f].pole = FALSE; + } + + counter++; + } + } + + if (mouse_b&Button3Mask) + { + static time_t bounce=0; + + if (bounce!=time(NULL)) + { + mouselook = !mouselook; + bounce=time(NULL); + } + } + + Cls(); + + x = -COASTER_WIDTH / 2; + y = 20.0; + z = start_z; + + if (mouselook) + { + ang_y = -(mouse_x - centre_x) * 2; + ang_x = (mouse_y - centre_y) * 2; + } + else + { + ang_x = atan(fabs(coaster[0].dy) / COASTER_Z_INC); + + if (isnan(ang_x)) + { + ang_x = 0; + } + else + { + ang_x = DEG(ang_x) * 10.0; + + if (coaster[0].dy > 0) + { + ang_x = -ang_x; + } + } + + ang_y = atan(fabs(coaster[0].dx) / COASTER_Z_INC); + + if (isnan(ang_y)) + { + ang_y = 0; + } + else + { + ang_y = DEG(ang_y) * 10.0; + + if (coaster[0].dx > 0) + { + ang_y = -ang_y; + } + } + } + + last_xp1.x = -1; + last_xp1.y = -1; + last_xp2.x = -1; + last_xp2.y = -1; + + start_z -= speed; + + /* + speed += coaster[0].dy / 10.0; + + if (speed < MIN_SPEED) + { + speed = MIN_SPEED; + } + + if (speed > MAX_SPEED) + { + speed = MAX_SPEED; + } + */ + + for(f = 0; f < COASTER_NUM; f++) + { + XPoint xp1, xp2; + + x += coaster[f].dx; + y += coaster[f].dy; + z += COASTER_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, &xp1) && + Project(rx2 + COASTER_WIDTH, ry2, rz2, &xp2)) + { + if (last_xp1.x != -1) + { + Line(last_xp1.x, last_xp1.y, xp1.x, xp1.y, white); + } + + if (last_xp2.x != -1) + { + Line(last_xp2.x, last_xp2.y, xp2.x, xp2.y, white); + } + + last_xp1 = xp1; + last_xp2 = xp2; + + if (coaster[f].bar) + { + Line(xp1.x, xp1.y, xp2.x, xp2.y, white); + } + + if (coaster[f].pole) + { + Line(xp1.x, xp1.y, xp1.x, height, white); + Line(xp2.x, xp2.y, xp2.x, height, white); + } + } + + if (start_z < 10.0) + { + if (f < COASTER_NUM - 1) + { + coaster[f] = coaster[f + 1]; + } + else + { + if (dcount == 0 && dx == 0 && dy == 0) + { + dcount = RND2(200, 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 < COASTER_Z_INC / 2.0 && + dx > -COASTER_Z_INC / 2.0) + { + dx += dxi; + } + + if (dy < COASTER_Z_INC / 2.0 && + dy > -COASTER_Z_INC / 2.0) + { + dy += dyi; + } + } + else + { + double sdx = SgnF(dx); + double sdy = SgnF(dy); + + if (dx != 0.0) + { + dx -= dxi; + } + + if (dy != 0.0) + { + dy -= dyi; + } + + if (SgnF(dx) != sdx) + { + dx = 0; + } + + if (SgnF(dy) != sdy) + { + dy = 0; + } + } + } + + coaster[f].dx = dx; + coaster[f].dy = dy; + + if ((counter % COASTER_BAR) == 0) + { + coaster[f].bar = TRUE; + } + else + { + coaster[f].bar = FALSE; + } + + if ((counter % COASTER_POLE) == 0) + { + coaster[f].pole = TRUE; + } + else + { + coaster[f].pole = FALSE; + } + + counter++; + } + } + } + + if (start_z < 10.0) + { + start_z += COASTER_Z_INC; + } +} + +#undef COASTER_NUM +#undef COASTER_WIDTH +#undef COASTER_Z_INC +#undef COASTER_BAR +#undef COASTER_POLE + + /* END OF FILE */ -- cgit v1.2.3