-/*
+/*
* Copyright (C) 2003 Robert Kooima
*
* NEVERBALL is free software; you can redistribute it and/or modify
#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
}
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];
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)
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);
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);
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)
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)
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);
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);
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;
}
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)
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)
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);
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);
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);
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);
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);
}
/*---------------------------------------------------------------------------*/
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);
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);
const float o[3],
const float w[3])
{
- float U[3], u, t = dt;
+ float U[3] = {0.0f, 0.0f, 0.0f}; /* init value only to avoid gcc warnings */
+ float u, t = dt;
int i;
/* Short circuit a non-solid lump. */
t = u;
}
}
-
+
/* Test all edges */
if (up->r > 0.0f)
/*---------------------------------------------------------------------------*/
-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)
}
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;
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;
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)
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;
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;