summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--xd.c345
1 files changed, 344 insertions, 1 deletions
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 */