summaryrefslogtreecommitdiff
path: root/xd.c
diff options
context:
space:
mode:
authorIan C <ianc@noddybox.co.uk>2018-10-23 14:35:41 +0000
committerIan C <ianc@noddybox.co.uk>2018-10-23 14:35:41 +0000
commit8b08533e3536d08d3d733aa424069f9a8d10300c (patch)
tree0f7f5726d9e05e7c798ed33abeea67706e7a48e5 /xd.c
parent74f15a9e50bb1bac10ff87da83214fdeb6f9b3dd (diff)
Added road demo.
Diffstat (limited to 'xd.c')
-rw-r--r--xd.c238
1 files changed, 235 insertions, 3 deletions
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 */