/* move.c v0.80 */ /* EB = Edward Boone */ /* epsilonbeta@geocities.com */ /* http://www.geocities.com/SiliconValley/Vista/6617/index.html */ /* Only nothing seems to be what it looks like */ /*---------------------------------------------------------------------------*/ /* #include */ #include "specific.h" /*---------------------------------------------------------------------------*/ /* #define */ #define DELAY_MIN 0 #define DELAY_MAX 3000 #define DELAY_STEP 100 #define EFF_MIN (ftofix(0.0)) #define EFF_MAX (ftofix(2.0)) #define EFF_STEP (ftofix(0.1)) #define SIZE_MIN 0 #define SIZE_MAX scr_h #define SIZE_STEP 1 #define XSIZE_MIN 0 #define XSIZE_MAX scr_w #define XSIZE_STEP 10 #define YSIZE_MIN 0 #define YSIZE_MAX scr_h #define YSIZE_STEP 10 /*---------------------------------------------------------------------------*/ /* variables */ int i, j, node_count, number, x, y; float F, G, M, angle, m, r, xforce, yforce; /* F = G * M * m / (r^2) */ BITMAP *pbmpe, *page1, *page2, *active_page; node nodes[MOVES_MAXNODES]; planet *space; int delayy, size, xsize, ysize; fixed eff; static tkeyparse see_f5_0 = {K_0, keysee_f5_0}, /* move.c specific */ see_f5_1 = {K_1, keysee_f5_1}, see_f5_2 = {K_2, keysee_f5_2}, see_f5_3 = {K_3, keysee_f5_3}, see_f5_4 = {K_4, keysee_f5_4}, see_f5_5 = {K_5, keysee_f5_5}, see_f5_6 = {K_6, keysee_f5_6}, see_f5_7 = {K_7, keysee_f5_7}, see_f5_8 = {K_8, keysee_f5_8}, see_f5_9 = {K_9, keysee_f5_9}, see_f5_D = {K_D, keysee_f5_D}, see_f5_E = {K_E, keysee_f5_E}, see_f5_S = {K_S, keysee_f5_S}, see_f5_T = {K_T, keysee_f5_T}, see_f5_U = {K_U, keysee_f5_U}, see_f5_d = {K_d, keysee_f5_d}, see_f5_e = {K_e, keysee_f5_e}, see_f5_s = {K_s, keysee_f5_s}, see_f5_t = {K_t, keysee_f5_t}, see_f5_u = {K_u, keysee_f5_u} ; tkeyparse* tkeyparsetbl_move[] = { TKEYPARSETBL_SEE, /* see.c specific */ &see_f5_0, /* move.c specific */ &see_f5_1, &see_f5_2, &see_f5_3, &see_f5_4, &see_f5_5, &see_f5_6, &see_f5_7, &see_f5_8, &see_f5_9, &see_f5_D, &see_f5_E, &see_f5_S, &see_f5_T, &see_f5_U, &see_f5_d, &see_f5_e, &see_f5_t, &see_f5_s, &see_f5_u, NULL }; teffect eff_move = { move_init, move_effect, move_loop_end, move_done, tkeyparsetbl_move, 1 }; /*---------------------------------------------------------------------------*/ int move_loop_end() { switch (lastkey) { COMMON_LOOP_END case K_D: case K_E: case K_S: case K_T: case K_U: case K_d: case K_e: case K_s: case K_t: case K_u: return 0; break; default: return 1; break; } } /*---------------------------------------------------------------------------*/ fixed node_dist(node n1, node n2) { fixed dx = itofix(n1.x - n2.x) / xsize; fixed dy = itofix(n1.y - n2.y) / ysize; return fsqrt(fmul(dx, dx) + fmul(dy, dy)) * xsize; } /*---------------------------------------------------------------------------*/ node dummy_node(node anode, node prev) { node n; /* 0 = 1 - (2 - 1) / 8 */ /* node_count = -1 - (-2 - -1) / 8 */ n.x = anode.x - (prev.x - anode.x) / 8; n.y = anode.y - (prev.y - anode.y) / 8; return n; } /*---------------------------------------------------------------------------*/ void calc_tangents() { int i; nodes[0] = dummy_node(nodes[1], nodes[2]); nodes[node_count] = dummy_node(nodes[node_count - 1], nodes[node_count - 2]); for (i = 1; i < node_count; i++) { nodes[i].tangent = fatan2(itofix(nodes[i + 1].y - nodes[i - 1].y), itofix(nodes[i + 1].x - nodes[i - 1].x)); } } /*---------------------------------------------------------------------------*/ void get_control_points(node n1, node n2, int points[8]) { fixed dist = fmul(node_dist(n1, n2), eff); points[0] = n1.x; points[1] = n1.y; points[2] = n1.x + fixtoi(fmul(fcos(n1.tangent), dist)); points[3] = n1.y + fixtoi(fmul(fsin(n1.tangent), dist)); points[4] = n2.x - fixtoi(fmul(fcos(n2.tangent), dist)); points[5] = n2.y - fixtoi(fmul(fsin(n2.tangent), dist)); points[6] = n2.x; points[7] = n2.y; } /*---------------------------------------------------------------------------*/ void grav_done() { } /*---------------------------------------------------------------------------*/ void grav_effect() { G = 0.4; for (i = 0; i < number; i++) { xforce = 0; yforce = 0; F = 0; M = space[i].mass; for (j = 0; j < number; j++) { if (j != i) /* don't process itself */ { /* not touching */ /* a lot faster, but less accurate, without multiplying space.size with size */ if (sqrt((space[i].x - space[j].x) * (space[i].x - space[j].x) + (space[i].y - space[j].y) * (space[i].y - space[j].y)) > (space[i].size + space[j].size) / 2) { m = space[j].mass; r = sqrt((space[j].x - space[i].x) * (space[j].x - space[i].x) + (space[j].y - space[i].y) * (space[j].y - space[i].y) ); F = G * M * m / r / r; angle = atan2((space[j].y - space[i].y), (space[j].x - space[i].x)); xforce += F * cos(angle); yforce += F * sin(angle); } } } /* F = m * a, accel = Force / mass */ space[i].xdir += xforce / (float)space[i].mass; space[i].ydir += yforce / (float)space[i].mass; } pbmpe = create_bitmapm(scr_w, scr_h); clear(pbmpe); vsync(); for (i = 0; i < number; i++) { x = (int)space[i].x + 160; /* erase */ y = (int)space[i].y + 100; stretch_blit(pbmpe, screen, 0, 0, pbmp->w, pbmp->h, x, y, space[i].size*size, space[i].size*size); space[i].x += space[i].xdir; /* move */ space[i].y += space[i].ydir; x = (int)space[i].x + 160; /* draw */ y = (int)space[i].y + 100; stretch_blit(pbmp, screen, 0, 0, pbmp->w, pbmp->h, x, y, space[i].size*size, space[i].size*size); } destroy_bitmapm(pbmpe); } /*---------------------------------------------------------------------------*/ void grav_init() { for (i = 0; i < number; i++) { space[i].x = rand() % 101 - 50; space[i].y = rand() % 101 - 50; space[i].xdir = 0; /* rand() % 11 - 5; */ space[i].ydir = 0; /* rand() % 11 - 5; */ } lastkey = K_d; clear(screen); } /*---------------------------------------------------------------------------*/ void keysee_f5_0() { keysee_f5_gen("f5_0"); } /*---------------------------------------------------------------------------*/ void keysee_f5_1() { keysee_f5_gen("f5_1"); } /*---------------------------------------------------------------------------*/ void keysee_f5_2() { keysee_f5_gen("f5_2"); } /*---------------------------------------------------------------------------*/ void keysee_f5_3() { keysee_f5_gen("f5_3"); } /*---------------------------------------------------------------------------*/ void keysee_f5_4() { keysee_f5_gen("f5_4"); } /*---------------------------------------------------------------------------*/ void keysee_f5_5() { keysee_f5_gen("f5_5"); } /*---------------------------------------------------------------------------*/ void keysee_f5_6() { keysee_f5_gen("f5_6"); } /*---------------------------------------------------------------------------*/ void keysee_f5_7() { keysee_f5_gen("f5_7"); } /*---------------------------------------------------------------------------*/ void keysee_f5_8() { keysee_f5_gen("f5_8"); } /*---------------------------------------------------------------------------*/ void keysee_f5_9() { keysee_f5_gen("f5_9"); } /*---------------------------------------------------------------------------*/ void keysee_f5_D() { paraint(&delayy, DELAY_MIN, DELAY_MAX, DELAY_STEP, 1, 0); } /*---------------------------------------------------------------------------*/ void keysee_f5_E() { parafixed(&eff, EFF_MIN, EFF_MAX, EFF_STEP, 1, 0); } /*---------------------------------------------------------------------------*/ void keysee_f5_S() { paraint(&size, SIZE_MIN, SIZE_MAX, SIZE_STEP, 1, 0); } /*---------------------------------------------------------------------------*/ void keysee_f5_T() { paraint(&xsize, XSIZE_MIN, XSIZE_MAX, XSIZE_STEP, 1, 0); } /*---------------------------------------------------------------------------*/ void keysee_f5_U() { paraint(&ysize, YSIZE_MIN, YSIZE_MAX, YSIZE_STEP, 1, 0); } /*---------------------------------------------------------------------------*/ void keysee_f5_d() { paraint(&delayy, DELAY_MIN, DELAY_MAX, DELAY_STEP, 0, 0); } /*---------------------------------------------------------------------------*/ void keysee_f5_e() { parafixed(&eff, EFF_MIN, EFF_MAX, EFF_STEP, 0, 0); } /*---------------------------------------------------------------------------*/ void keysee_f5_gen(uchr s[256]) { int i; char s1[256]; FILE *fp; fp = fopen(confname, "rt"); if (!fp) { fp = fopenm(DEFNAME, "rt"); } setfilept(fp, s, 0); fscanf(fp, "%s", s1); /* skip = */ fscanf(fp, "%s", s1); /* skip move */ fscanf(fp, "%s", s1); /* read sort */ eff_move.asort = atoi(s1); if (eff_move.asort == 1) { fscanf(fp, "%s", s1); /* read delayy */ delayy = atoi(s1); fscanf(fp, "%s", s1); /* read eff 0.25 */ eff = ftofix(atof(s1)); fscanf(fp, "%s", s1); /* read width in pixels */ xsize = atoi(s1); fscanf(fp, "%s", s1); /* read heigth in pixels */ ysize = atoi(s1); /* node_count : number of (x,y)-points that follow */ fscanf(fp, "%s", s1); node_count = atoi(s1); for (i = 1; i <= node_count; i++) { fscanf(fp, "%s", s1); /* read x */ nodes[i].x = atoi(s1); fscanf(fp, "%s", s1); /* read y */ nodes[i].y = atoi(s1); } /* node_count becomes one more than number of parameters read */ node_count++; } else if (eff_move.asort == 2) { fscanf(fp, "%s", s1); /* read delayy */ delayy = atoi(s1); fscanf(fp, "%s", s1); /* read size multiplicator */ size = atoi(s1); fscanf(fp, "%i", &number); /* read number of planets */ space = (planet *) mallocm(sizeof(planet) * number); for (i = 0; i < number; i++) /* for each planet */ { fscanf(fp, "%f", &space[i].x); /* read x */ fscanf(fp, "%f", &space[i].y); /* read y */ fscanf(fp, "%f", &space[i].xdir); /* read x velocity */ fscanf(fp, "%f", &space[i].ydir); /* read y velocity */ fscanf(fp, "%i", &space[i].size); /* read radius in pixels */ fscanf(fp, "%i", &space[i].mass); /* read mass */ } } do_effect(&eff_move); } /*---------------------------------------------------------------------------*/ void keysee_f5_s() { paraint(&size, SIZE_MIN, SIZE_MAX, SIZE_STEP, 0, 0); } /*---------------------------------------------------------------------------*/ void keysee_f5_t() { paraint(&xsize, XSIZE_MIN, XSIZE_MAX, XSIZE_STEP, 0, 0); } /*---------------------------------------------------------------------------*/ void keysee_f5_u() { paraint(&ysize, YSIZE_MIN, YSIZE_MAX, YSIZE_STEP, 0, 0); } /*---------------------------------------------------------------------------*/ void move_done() { moves_done(); grav_done(); } /*---------------------------------------------------------------------------*/ void move_effect(int asort) { switch (asort) { case 1: moves_effect(); break; case 2: grav_effect(); break; } rest(delayy); } /*---------------------------------------------------------------------------*/ void move_init() { moves_init(); grav_init(); } /*---------------------------------------------------------------------------*/ void moves_done() { set_gfx_modem(GFX_VGA, 320, 200, 0, 0); scr_w = SCREEN_W; scr_h = SCREEN_H; npixels = scr_w * scr_h; set_palette(pal); destroy_bitmapm(pbmpe); destroy_bitmapm(page1); destroy_bitmapm(page2); destroy_bitmapm(active_page); } /*---------------------------------------------------------------------------*/ void moves_effect() { clear(pbmpe); active_page = page2; walk(); clear(page1); clear(page2); } /*---------------------------------------------------------------------------*/ void moves_init() { set_gfx_modem(GFX_MODEX, 320, 200, 0, 400); scr_w = SCREEN_W; scr_h = SCREEN_H; npixels = scr_w * scr_h; set_palette(pal); calc_tangents(); pbmpe = create_bitmapm(scr_w, scr_h); page1 = create_sub_bitmap(screen, 0, 0, scr_w, scr_h); page2 = create_sub_bitmap(screen, 0, scr_h, scr_w, scr_h); lastkey = K_d; } /*---------------------------------------------------------------------------*/ /* moves a sprite along the spline path */ void walk() { int points[8]; int x[MOVES_MAXPOINTS], y[MOVES_MAXPOINTS]; int i, n, npoints, ox, oy; clear(screen); ox = -16; oy = -16; for (n = 1; !(kbhit()); n++) { if (n >= (node_count - 1)) { n = 1; } npoints = (fixtoi(node_dist(nodes[n], nodes[n + 1])) + 3) / 4; if (npoints < 1) { npoints = 1; } else if (npoints > MOVES_MAXPOINTS) { npoints = MOVES_MAXPOINTS; } get_control_points(nodes[n], nodes[n + 1], points); calc_spline(points, npoints, x, y); for (i = 1; i < npoints; i++) { clear(active_page); stretch_blit(pbmp, active_page, 0, 0, pbmp->w, pbmp->h, x[i], y[i], xsize, ysize); if (active_page == page1) { scroll_screen(0, 0); active_page = page2; } else { scroll_screen(0, scr_h); active_page = page1; } ox = x[i]; oy = y[i]; } } scroll_screen(0, 0); }