updated URL of forum and table in readme file
[neverball] / share / solid.c
index 4bb31d9..467da87 100644 (file)
@@ -30,7 +30,7 @@
 #include "binary.h"
 
 #define MAGIC       0x4c4f53af
-#define SOL_VERSION 5
+#define SOL_VERSION 6
 
 #define LARGE 1.0e+5f
 
@@ -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)
@@ -253,6 +254,7 @@ static int sol_load_file(FILE *fin, struct s_file *fp)
     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);
@@ -263,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);
@@ -271,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)
@@ -293,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)
@@ -309,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);
@@ -322,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);
@@ -331,7 +335,49 @@ 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;
 }
@@ -349,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)
@@ -439,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)
@@ -509,6 +569,7 @@ 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);
@@ -519,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);
@@ -527,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);
@@ -539,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);
@@ -547,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);
 }
 
 /*---------------------------------------------------------------------------*/
@@ -579,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);
@@ -1254,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];
+            p[0] = fp->hv[hi].p[0];
+            p[1] = fp->hv[hi].p[1];
+            p[2] = fp->hv[hi].p[2];
 
-            n = fp->cv[ci].n;
-            fp->cv[ci].n = 0;
-
-            return n;
+            return &fp->hv[hi];
         }
     }
-    return 0;
+    return NULL;
 }
 
 struct s_goal *sol_goal_test(struct s_file *fp, float *p, int ui)