X-Git-Url: http://vcs.maemo.org/git/?a=blobdiff_plain;f=share%2Fsolid.c;h=467da8774a9f613d18c763bf601813fda92688db;hb=90baa3b05af80b5996bb2eecebd58ca2ceb53acf;hp=7a5e3a9f5a4dae4276f94776f7c67535dd8f6e07;hpb=8680c935510a56807d132d3807571bd67bf4cac6;p=neverball diff --git a/share/solid.c b/share/solid.c index 7a5e3a9..467da87 100644 --- a/share/solid.c +++ b/share/solid.c @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2003 Robert Kooima * * NEVERBALL is free software; you can redistribute it and/or modify @@ -29,8 +29,8 @@ #include "base_config.h" #include "binary.h" -#define MAGIC 0x4F425251 /* Neverball sol file magic number (should not change) */ -#define SOL_VERSION 4 /* Neverball sol file format version (can change) */ +#define MAGIC 0x4c4f53af +#define SOL_VERSION 6 #define LARGE 1.0e+5f @@ -69,8 +69,8 @@ static void sol_body_v(float v[3], } void sol_body_p(float p[3], - const struct s_file *fp, - const struct s_body *bp) + const struct s_file *fp, + const struct s_body *bp) { float v[3]; @@ -180,10 +180,11 @@ static void sol_load_body(FILE *fin, struct s_body *bp) get_index(fin, &bp->gc); } -static void sol_load_coin(FILE *fin, struct s_coin *cp) +static void sol_load_item(FILE *fin, struct s_item *hp) { - get_array(fin, cp->p, 3); - get_index(fin, &cp->n); + get_array(fin, hp->p, 3); + get_index(fin, &hp->t); + get_index(fin, &hp->n); } static void sol_load_goal(FILE *fin, struct s_goal *zp) @@ -249,9 +250,11 @@ static int sol_load_file(FILE *fin, struct s_file *fp) get_index(fin, &magic); get_index(fin, &version); + if (magic != MAGIC || version != SOL_VERSION) return 0; + get_index(fin, &fp->ac); get_index(fin, &fp->mc); get_index(fin, &fp->vc); get_index(fin, &fp->ec); @@ -262,7 +265,7 @@ static int sol_load_file(FILE *fin, struct s_file *fp) get_index(fin, &fp->nc); get_index(fin, &fp->pc); get_index(fin, &fp->bc); - get_index(fin, &fp->cc); + get_index(fin, &fp->hc); get_index(fin, &fp->zc); get_index(fin, &fp->jc); get_index(fin, &fp->xc); @@ -270,8 +273,9 @@ static int sol_load_file(FILE *fin, struct s_file *fp) get_index(fin, &fp->uc); get_index(fin, &fp->wc); get_index(fin, &fp->ic); - get_index(fin, &fp->ac); + if (fp->ac) + fp->av = (char *) calloc(fp->ac, sizeof (char)); if (fp->mc) fp->mv = (struct s_mtrl *) calloc(fp->mc, sizeof (struct s_mtrl)); if (fp->vc) @@ -292,8 +296,8 @@ static int sol_load_file(FILE *fin, struct s_file *fp) fp->pv = (struct s_path *) calloc(fp->pc, sizeof (struct s_path)); if (fp->bc) fp->bv = (struct s_body *) calloc(fp->bc, sizeof (struct s_body)); - if (fp->cc) - fp->cv = (struct s_coin *) calloc(fp->cc, sizeof (struct s_coin)); + if (fp->hc) + fp->hv = (struct s_item *) calloc(fp->hc, sizeof (struct s_item)); if (fp->zc) fp->zv = (struct s_goal *) calloc(fp->zc, sizeof (struct s_goal)); if (fp->jc) @@ -308,8 +312,9 @@ static int sol_load_file(FILE *fin, struct s_file *fp) fp->wv = (struct s_view *) calloc(fp->wc, sizeof (struct s_view)); if (fp->ic) fp->iv = (int *) calloc(fp->ic, sizeof (int)); + if (fp->ac) - fp->av = (char *) calloc(fp->ac, sizeof (char)); + fread(fp->av, 1, fp->ac, fin); for (i = 0; i < fp->mc; i++) sol_load_mtrl(fin, fp->mv + i); for (i = 0; i < fp->vc; i++) sol_load_vert(fin, fp->vv + i); @@ -321,7 +326,7 @@ static int sol_load_file(FILE *fin, struct s_file *fp) for (i = 0; i < fp->nc; i++) sol_load_node(fin, fp->nv + i); for (i = 0; i < fp->pc; i++) sol_load_path(fin, fp->pv + i); for (i = 0; i < fp->bc; i++) sol_load_body(fin, fp->bv + i); - for (i = 0; i < fp->cc; i++) sol_load_coin(fin, fp->cv + i); + for (i = 0; i < fp->hc; i++) sol_load_item(fin, fp->hv + i); for (i = 0; i < fp->zc; i++) sol_load_goal(fin, fp->zv + i); for (i = 0; i < fp->jc; i++) sol_load_jump(fin, fp->jv + i); for (i = 0; i < fp->xc; i++) sol_load_swch(fin, fp->xv + i); @@ -330,8 +335,50 @@ static int sol_load_file(FILE *fin, struct s_file *fp) for (i = 0; i < fp->wc; i++) sol_load_view(fin, fp->wv + i); for (i = 0; i < fp->ic; i++) get_index(fin, fp->iv + i); - if (fp->ac) fread(fp->av, 1, fp->ac, fin); - + return 1; +} + +static int sol_load_head(FILE *fin, struct s_file *fp) +{ + int magic; + int version; + + get_index(fin, &magic); + get_index(fin, &version); + + if (magic != MAGIC || version != SOL_VERSION) + return 0; + + get_index(fin, &fp->ac); + +#if 0 + get_index(fin, &fp->mc); + get_index(fin, &fp->vc); + get_index(fin, &fp->ec); + get_index(fin, &fp->sc); + get_index(fin, &fp->tc); + get_index(fin, &fp->gc); + get_index(fin, &fp->lc); + get_index(fin, &fp->nc); + get_index(fin, &fp->pc); + get_index(fin, &fp->bc); + get_index(fin, &fp->hc); + get_index(fin, &fp->zc); + get_index(fin, &fp->jc); + get_index(fin, &fp->xc); + get_index(fin, &fp->rc); + get_index(fin, &fp->uc); + get_index(fin, &fp->wc); + get_index(fin, &fp->ic); +#endif + fseek(fin, 18 * 4, SEEK_CUR); + + if (fp->ac) + { + fp->av = (char *) calloc(fp->ac, sizeof (char)); + fread(fp->av, 1, fp->ac, fin); + } + return 1; } @@ -348,6 +395,19 @@ int sol_load_only_file(struct s_file *fp, const char *filename) return res; } +int sol_load_only_head(struct s_file *fp, const char *filename) +{ + FILE *fin; + int res = 0; + + if ((fin = fopen(filename, FMODE_RB))) + { + res = sol_load_head(fin, fp); + fclose(fin); + } + return res; +} + /*---------------------------------------------------------------------------*/ static void sol_stor_mtrl(FILE *fout, struct s_mtrl *mp) @@ -438,10 +498,11 @@ static void sol_stor_body(FILE *fout, struct s_body *bp) put_index(fout, &bp->gc); } -static void sol_stor_coin(FILE *fout, struct s_coin *cp) +static void sol_stor_item(FILE *fout, struct s_item *hp) { - put_array(fout, cp->p, 3); - put_index(fout, &cp->n); + put_array(fout, hp->p, 3); + put_index(fout, &hp->t); + put_index(fout, &hp->n); } static void sol_stor_goal(FILE *fout, struct s_goal *zp) @@ -507,7 +568,8 @@ static void sol_stor_file(FILE *fin, struct s_file *fp) put_index(fin, &magic); put_index(fin, &version); - + + put_index(fin, &fp->ac); put_index(fin, &fp->mc); put_index(fin, &fp->vc); put_index(fin, &fp->ec); @@ -518,7 +580,7 @@ static void sol_stor_file(FILE *fin, struct s_file *fp) put_index(fin, &fp->nc); put_index(fin, &fp->pc); put_index(fin, &fp->bc); - put_index(fin, &fp->cc); + put_index(fin, &fp->hc); put_index(fin, &fp->zc); put_index(fin, &fp->jc); put_index(fin, &fp->xc); @@ -526,8 +588,8 @@ static void sol_stor_file(FILE *fin, struct s_file *fp) put_index(fin, &fp->uc); put_index(fin, &fp->wc); put_index(fin, &fp->ic); - put_index(fin, &fp->ac); + fwrite(fp->av, 1, fp->ac, fin); for (i = 0; i < fp->mc; i++) sol_stor_mtrl(fin, fp->mv + i); for (i = 0; i < fp->vc; i++) sol_stor_vert(fin, fp->vv + i); for (i = 0; i < fp->ec; i++) sol_stor_edge(fin, fp->ev + i); @@ -538,7 +600,7 @@ static void sol_stor_file(FILE *fin, struct s_file *fp) for (i = 0; i < fp->nc; i++) sol_stor_node(fin, fp->nv + i); for (i = 0; i < fp->pc; i++) sol_stor_path(fin, fp->pv + i); for (i = 0; i < fp->bc; i++) sol_stor_body(fin, fp->bv + i); - for (i = 0; i < fp->cc; i++) sol_stor_coin(fin, fp->cv + i); + for (i = 0; i < fp->hc; i++) sol_stor_item(fin, fp->hv + i); for (i = 0; i < fp->zc; i++) sol_stor_goal(fin, fp->zv + i); for (i = 0; i < fp->jc; i++) sol_stor_jump(fin, fp->jv + i); for (i = 0; i < fp->xc; i++) sol_stor_swch(fin, fp->xv + i); @@ -546,8 +608,6 @@ static void sol_stor_file(FILE *fin, struct s_file *fp) for (i = 0; i < fp->uc; i++) sol_stor_ball(fin, fp->uv + i); for (i = 0; i < fp->wc; i++) sol_stor_view(fin, fp->wv + i); for (i = 0; i < fp->ic; i++) put_index(fin, fp->iv + i); - - fwrite(fp->av, 1, fp->ac, fin); } /*---------------------------------------------------------------------------*/ @@ -578,7 +638,7 @@ void sol_free(struct s_file *fp) if (fp->nv) free(fp->nv); if (fp->pv) free(fp->pv); if (fp->bv) free(fp->bv); - if (fp->cv) free(fp->cv); + if (fp->hc) free(fp->hv); if (fp->zv) free(fp->zv); if (fp->jv) free(fp->jv); if (fp->xv) free(fp->xv); @@ -781,7 +841,7 @@ static float sol_bounce(struct s_ball *up, v_mad(u, w, n, -wn); v_mad(v, v, n, -vn); v_mad(v, v, u, +km * dt); - v_mad(v, v, n, xn + yn); + v_mad(v, v, n, xn + yn); v_mad(p, q, n, up->r); @@ -1021,7 +1081,7 @@ static float sol_test_lump(float dt, const float o[3], const float w[3]) { - float U[3] = {0.0f, 0.0f, 0.0f}; /* set some init value only for avoid gcc warnings */ + float U[3] = {0.0f, 0.0f, 0.0f}; /* init value only to avoid gcc warnings */ float u, t = dt; int i; @@ -1042,7 +1102,7 @@ static float sol_test_lump(float dt, t = u; } } - + /* Test all edges */ if (up->r > 0.0f) @@ -1253,33 +1313,31 @@ float sol_step(struct s_file *fp, const float *g, float dt, int ui, int *m) /*---------------------------------------------------------------------------*/ -int sol_coin_test(struct s_file *fp, float *p, float coin_r) +struct s_item *sol_item_test(struct s_file *fp, float *p, float item_r) { const float *ball_p = fp->uv->p; const float ball_r = fp->uv->r; - int ci, n; - for (ci = 0; ci < fp->cc; ci++) + int hi; + + for (hi = 0; hi < fp->hc; hi++) { float r[3]; - r[0] = ball_p[0] - fp->cv[ci].p[0]; - r[1] = ball_p[1] - fp->cv[ci].p[1]; - r[2] = ball_p[2] - fp->cv[ci].p[2]; + r[0] = ball_p[0] - fp->hv[hi].p[0]; + r[1] = ball_p[1] - fp->hv[hi].p[1]; + r[2] = ball_p[2] - fp->hv[hi].p[2]; - if (fp->cv[ci].n > 0 && v_len(r) < ball_r + coin_r) + if (fp->hv[hi].t != ITEM_NONE && v_len(r) < ball_r + item_r) { - p[0] = fp->cv[ci].p[0]; - p[1] = fp->cv[ci].p[1]; - p[2] = fp->cv[ci].p[2]; - - n = fp->cv[ci].n; - fp->cv[ci].n = 0; + p[0] = fp->hv[hi].p[0]; + p[1] = fp->hv[hi].p[1]; + p[2] = fp->hv[hi].p[2]; - return n; + return &fp->hv[hi]; } } - return 0; + return NULL; } struct s_goal *sol_goal_test(struct s_file *fp, float *p, int ui) @@ -1311,10 +1369,10 @@ struct s_goal *sol_goal_test(struct s_file *fp, float *p, int ui) } int sol_jump_test(struct s_file *fp, float *p, int ui) -/* Test if the ball ui in inside a jump */ -/* Return 1 if yes and fill p with the destination position */ -/* Return 0 if no */ -/* Return 2 if the ball is on the border of a jump */ +/* Test if the ball ui is inside a jump. */ +/* Return 1 if yes and fill p with the destination position. */ +/* Return 0 if no. */ +/* Return 2 if the ball is on the border of a jump. */ { const float *ball_p = fp->uv[ui].p; const float ball_r = fp->uv[ui].r; @@ -1330,30 +1388,30 @@ int sol_jump_test(struct s_file *fp, float *p, int ui) r[1] = ball_p[2] - fp->jv[ji].p[2]; r[2] = 0; - l = v_len(r) - fp->jv[ji].r; + l = v_len(r) - fp->jv[ji].r; if (l < 0 && ball_p[1] > fp->jv[ji].p[1] && ball_p[1] < fp->jv[ji].p[1] + JUMP_HEIGHT / 2) { - if (l < - ball_r ) - { - p[0] = fp->jv[ji].q[0] + (ball_p[0] - fp->jv[ji].p[0]); - p[1] = fp->jv[ji].q[1] + (ball_p[1] - fp->jv[ji].p[1]); - p[2] = fp->jv[ji].q[2] + (ball_p[2] - fp->jv[ji].p[2]); - - return 1; - } - else - res = 2; + if (l < - ball_r ) + { + p[0] = fp->jv[ji].q[0] + (ball_p[0] - fp->jv[ji].p[0]); + p[1] = fp->jv[ji].q[1] + (ball_p[1] - fp->jv[ji].p[1]); + p[2] = fp->jv[ji].q[2] + (ball_p[2] - fp->jv[ji].p[2]); + + return 1; + } + else + res = 2; } } return res; } int sol_swch_test(struct s_file *fp, int ui) -/* In the sol fp, test and process the event the ball ui enters a switch - * return 1 if a visibla switch is activated - * return 0 else (no switch is activated or only invisible switchs) */ +/* In the SOL fp, test and process the event the ball ui enters a switch. + * Return 1 if a visible switch is activated, return 0 otherwise (no switch is + * activated or only invisible switchs) */ { const float *ball_p = fp->uv[ui].p; const float ball_r = fp->uv[ui].r; @@ -1373,7 +1431,7 @@ int sol_swch_test(struct s_file *fp, int ui) r[1] = ball_p[2] - xp->p[2]; r[2] = 0; - l = v_len(r) - xp->r; + l = v_len(r) - xp->r; if (l < ball_r && ball_p[1] > xp->p[1] && ball_p[1] < xp->p[1] + SWCH_HEIGHT / 2) @@ -1383,10 +1441,10 @@ int sol_swch_test(struct s_file *fp, int ui) int pi = xp->pi; int pj = xp->pi; - /* The ball enter */ - if (xp->t0 == 0) - xp->e = 1; - + /* The ball enter */ + if (xp->t0 == 0) + xp->e = 1; + /* Toggle the state, update the path. */ xp->f = xp->f ? 0 : 1; @@ -1407,14 +1465,14 @@ int sol_swch_test(struct s_file *fp, int ui) if (xp->f != xp->f0) xp->t = xp->t0; - /* If visible, set the result */ - if (!xp->i) - res = 1; + /* If visible, set the result */ + if (!xp->i) + res = 1; } } - else if (xp->e) - /* A ball go out */ - xp->e = 0; + else if (xp->e) + /* A ball go out */ + xp->e = 0; } } return res;